summaryrefslogtreecommitdiff
path: root/utils/atj2137
diff options
context:
space:
mode:
Diffstat (limited to 'utils/atj2137')
-rw-r--r--utils/atj2137/atjboottool/Makefile2
-rw-r--r--utils/atj2137/atjboottool/afi.h29
-rw-r--r--utils/atj2137/atjboottool/atjboottool.c1092
-rw-r--r--utils/atj2137/atjboottool/fwu.c1034
-rw-r--r--utils/atj2137/atjboottool/fwu.h40
-rw-r--r--utils/atj2137/atjboottool/misc.c7
-rw-r--r--utils/atj2137/atjboottool/misc.h11
7 files changed, 1143 insertions, 1072 deletions
diff --git a/utils/atj2137/atjboottool/Makefile b/utils/atj2137/atjboottool/Makefile
index 14f25475f6..31c315d4fd 100644
--- a/utils/atj2137/atjboottool/Makefile
+++ b/utils/atj2137/atjboottool/Makefile
@@ -10,7 +10,7 @@ all: $(BINS)
10%.o: %.c 10%.o: %.c
11 $(CC) $(CFLAGS) -c -o $@ $< 11 $(CC) $(CFLAGS) -c -o $@ $<
12 12
13atjboottool: atjboottool.o misc.o atj_tables.o 13atjboottool: atjboottool.o fwu.o misc.o atj_tables.o
14 $(LD) -o $@ $^ $(LDFLAGS) 14 $(LD) -o $@ $^ $(LDFLAGS)
15 15
16clean: 16clean:
diff --git a/utils/atj2137/atjboottool/afi.h b/utils/atj2137/atjboottool/afi.h
new file mode 100644
index 0000000000..bb264cefdf
--- /dev/null
+++ b/utils/atj2137/atjboottool/afi.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2017 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __AFI_H__
22#define __AFI_H__
23
24#include <stdint.h>
25
26/* Check if a file looks like a FWU file */
27bool afi_check(uint8_t *buf, size_t size);
28
29#endif /* __AFI_H__ */
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 }
diff --git a/utils/atj2137/atjboottool/fwu.c b/utils/atj2137/atjboottool/fwu.c
new file mode 100644
index 0000000000..843a1cb628
--- /dev/null
+++ b/utils/atj2137/atjboottool/fwu.c
@@ -0,0 +1,1034 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2017 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <string.h>
22#include <stdlib.h>
23#include "misc.h"
24#include "fwu.h"
25#include "afi.h"
26
27#define check_field(v_exp, v_have, str_ok, str_bad) \
28 if((v_exp) != (v_have)) \
29 { cprintf(RED, str_bad); return 1; } \
30 else { cprintf(RED, str_ok); }
31
32#define FWU_SIG_SIZE 16
33#define FWU_BLOCK_SIZE 512
34
35struct fwu_hdr_t
36{
37 uint8_t sig[FWU_SIG_SIZE];
38 uint32_t fw_size;
39 uint32_t block_size;// always 512
40 uint8_t version;
41 uint8_t unk;
42 uint8_t sig2[FWU_SIG_SIZE];
43} __attribute__((packed));
44
45const uint8_t g_fwu_signature[FWU_SIG_SIZE] =
46{
47 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x75
48};
49
50struct version_desc_t
51{
52 uint8_t version;
53 uint8_t value;
54 uint8_t unk;
55 uint8_t sig2[FWU_SIG_SIZE];
56};
57
58struct version_desc_t g_version[] =
59{
60 { 1, 0xd, 0xd0, { 0x76, 0x5c, 0x50, 0x94, 0x69, 0xb0, 0xa7, 0x03, 0x10, 0xf1, 0x7e, 0xdb, 0x88, 0x90, 0x86, 0x9d } },
61 { 1, 0xe, 0xd0, { 0x92, 0x22, 0x7a, 0x77, 0x08, 0x67, 0xae, 0x06, 0x16, 0x06, 0xb8, 0x65, 0xa6, 0x42, 0xf7, 0X52 } },
62 { 3, 0x7e, 0xe1, { 0x3f, 0xad, 0xf8, 0xb0, 0x2e, 0xaf, 0x67, 0x49, 0xb9, 0x85, 0x5f, 0x63, 0x4e, 0x5e, 0x8e, 0x2e } },
63};
64
65#define NR_VERSIONS (int)(sizeof(g_version)/sizeof(g_version[0]))
66
67typedef struct ptr_bundle_t
68{
69 uint32_t *ptrA;
70 uint32_t *ptrB;
71}ptr_bundle_t;
72
73struct block_A_info_t
74{
75 int nr_bits;
76 uint16_t field_2;
77 int nr_words;
78 int nr_dwords_x12;
79 uint32_t *ptr6; // size
80 uint32_t *ptr7; // size
81 uint32_t *ptr5; // size
82 uint32_t size;
83 uint32_t field_1C;
84 ptr_bundle_t ptr1;
85 uint32_t *ptr3; // size
86 uint32_t *ptr4; // size
87 int nr_words2;
88 uint32_t field_34;
89 int nr_dwords_x8;
90 int nr_bytes;
91 int nr_bytes2;
92 int nr_dwords_m1;
93 int nr_dwords_x2_m1;
94 int nr_dwords_x2;
95 int nr_dwords;
96 uint32_t field_54;
97 uint32_t field_58;
98};
99
100struct block_A_info_t g_decode_A_info;
101uint8_t g_subblock_A[0x128];
102uint8_t g_key_B[20];
103uint8_t g_perm_B[258];
104uint8_t g_crypto_info_byte;
105uint8_t *g_decode_buffer;
106uint8_t *g_decode_buffer2;
107void *g_decode_buffer3;
108
109#include "atj_tables.h"
110
111void compute_checksum(uint8_t *buf, size_t size, uint8_t t[20])
112{
113 memset(t, 0, 20);
114
115 for(size_t i = 0; i < size; i++)
116 t[i % 20] ^= buf[i];
117 for(int i = 0; i < 20; i++)
118 t[i] = ~t[i];
119}
120
121int check_block(uint8_t *buf, uint8_t ref[20], unsigned size)
122{
123 uint8_t t[20];
124 compute_checksum(buf, size, t);
125
126 return memcmp(ref, t, 20);
127}
128
129
130int get_version(uint8_t *buf, unsigned long size)
131{
132 (void) size;
133 struct fwu_hdr_t *hdr = (void *)buf;
134 for(int i = 0; i < NR_VERSIONS; i++)
135 if(hdr->version == g_version[i].value)
136 return i;
137 return -1;
138}
139
140static int decode_block_A(uint8_t block[1020])
141{
142 uint8_t *p = &g_check_block_A_table[32 * (block[998] & 0x1f)];
143 uint8_t key[32];
144
145 for(int i = 0; i < 20; i++)
146 {
147 block[1000 + i] ^= p[i];
148 key[i] = block[1000 + i];
149 }
150 for(int i = 20; i < 32; i++)
151 key[i] = key[i - 20];
152
153 for(int i = 0; i < 992; i++)
154 block[i] ^= key[i % 32] ^ g_check_block_A_table[i];
155
156 return check_block(block - 1, block + 1000, 1001);
157}
158
159static void compute_perm(uint8_t *keybuf, size_t size, uint8_t perm[258])
160{
161 for(int i = 0; i < 256; i++)
162 perm[i] = i;
163 perm[256] = perm[257] = 0;
164 uint8_t idx = 0;
165 for(int i = 0; i < 256; i++)
166 {
167 uint8_t v = perm[i];
168 idx = (v + keybuf[i % size] + idx) % 256;
169 perm[i] = perm[idx];
170 perm[idx] = v;
171 }
172}
173
174static void decode_perm(uint8_t *buf, size_t size, uint8_t perm[258])
175{
176 uint8_t idxa = perm[256];
177 uint8_t idxb = perm[257];
178 for(size_t i = 0; i < size; i++)
179 {
180 idxa = (idxa + 1) % 256;
181 uint8_t v = perm[idxa];
182 idxb = (idxb + v) % 256;
183 perm[idxa] = perm[idxb];
184 perm[idxb] = v;
185 buf[i] ^= perm[(v + perm[idxa]) % 256];
186 }
187}
188
189static void decode_block_with_perm(uint8_t *keybuf, int keysize,
190 uint8_t *buf, int bufsize, uint8_t perm[258])
191{
192 compute_perm(keybuf, keysize, perm);
193 decode_perm(buf, bufsize, perm);
194}
195
196static void apply_perm(uint8_t *inbuf, uint8_t *outbuf, size_t size, int swap)
197{
198 memcpy(outbuf, inbuf, size);
199 int a = swap & 0xf;
200 int b = (swap >> 4) + 16;
201 uint8_t v = outbuf[a];
202 outbuf[a] = outbuf[b];
203 outbuf[b] = v;
204}
205
206static void decode_block_with_swap(uint8_t keybuf[32], int swap,
207 uint8_t *buf, int bufsize, uint8_t perm[258])
208{
209 uint8_t keybuf_interm[32];
210
211 apply_perm(keybuf, keybuf_interm, 32, swap);
212 decode_block_with_perm(keybuf_interm, 32, buf, bufsize, perm);
213}
214
215static void clear_memory(void *buf, size_t size_dwords)
216{
217 memset(buf, 0, 4 * size_dwords);
218}
219
220static void set_bit(int bit_pos, uint32_t *buf)
221{
222 buf[bit_pos / 32] |= 1 << (bit_pos % 32);
223}
224
225static int fill_decode_info(uint8_t sz)
226{
227 if(sz == 2) sz = 233;
228 else if(sz == 3) sz = 163;
229 else return 1;
230
231 g_decode_A_info.nr_bits = sz;
232 g_decode_A_info.nr_bytes2 = sz / 8 + (sz % 8 != 0);
233 g_decode_A_info.nr_words = 2 * g_decode_A_info.nr_bytes2;
234 g_decode_A_info.nr_bytes = sz / 8 + (sz % 8 != 0);
235 g_decode_A_info.nr_words2 = 2 * g_decode_A_info.nr_bytes2;
236 g_decode_A_info.nr_dwords = sz / 32 + (sz % 32 != 0);
237 g_decode_A_info.size = 4 * g_decode_A_info.nr_dwords;
238 g_decode_A_info.nr_dwords_x8 = 8 * g_decode_A_info.nr_dwords;
239 g_decode_A_info.nr_dwords_m1 = g_decode_A_info.nr_dwords - 1;
240 g_decode_A_info.nr_dwords_x2 = 2 * g_decode_A_info.nr_dwords;
241 g_decode_A_info.nr_dwords_x2_m1 = g_decode_A_info.nr_dwords_x2 - 1;
242 g_decode_A_info.nr_dwords_x12 = 12 * g_decode_A_info.nr_dwords;
243 g_decode_A_info.ptr1.ptrA = malloc(4 * g_decode_A_info.nr_dwords);
244 g_decode_A_info.ptr1.ptrB = malloc(g_decode_A_info.size);
245 g_decode_A_info.ptr3 = malloc(g_decode_A_info.size);
246 g_decode_A_info.ptr4 = malloc(g_decode_A_info.size);
247 g_decode_A_info.ptr5 = malloc(g_decode_A_info.size);
248 g_decode_A_info.ptr6 = malloc(g_decode_A_info.size);
249 g_decode_A_info.ptr7 = malloc(g_decode_A_info.size);
250
251 cprintf(BLUE, " Decode Info:\n");
252 cprintf_field(" Nr Bits: ", "%d\n", g_decode_A_info.nr_bits);
253 cprintf_field(" Nr Bytes: ", "%d\n", g_decode_A_info.nr_bytes);
254 cprintf_field(" Nr Bytes 2: ", "%d\n", g_decode_A_info.nr_bytes2);
255 cprintf_field(" Nr Words: ", "%d\n", g_decode_A_info.nr_words);
256 cprintf_field(" Nr Words 2: ", "%d\n", g_decode_A_info.nr_words2);
257 cprintf_field(" Nr DWords: ", "%d\n", g_decode_A_info.nr_dwords);
258 cprintf_field(" Size: ", "%d\n", g_decode_A_info.size);
259
260 return 0;
261}
262
263static int process_block_A(uint8_t block[1024])
264{
265 cprintf(BLUE, "Block A\n");
266 int ret = decode_block_A(block + 4);
267 cprintf(GREEN, " Check: ");
268 check_field(ret, 0, "Pass\n", "Fail\n");
269
270 memcpy(g_subblock_A, block, sizeof(g_subblock_A));
271 ret = fill_decode_info(g_subblock_A[276]);
272 cprintf(GREEN, " Info: ");
273 check_field(ret, 0, "Pass\n", "Fail\n");
274
275 int tmp = 2 * g_decode_A_info.nr_bytes2 + 38;
276 int offset = 1004 - tmp + 5;
277 g_crypto_info_byte = block[offset - 1];
278 g_decode_buffer = malloc(g_decode_A_info.size);
279 g_decode_buffer2 = malloc(g_decode_A_info.size);
280
281 memset(g_decode_buffer, 0, g_decode_A_info.size);
282 memset(g_decode_buffer2, 0, g_decode_A_info.size);
283
284 memcpy(g_decode_buffer, &block[offset], g_decode_A_info.nr_bytes2);
285 int offset2 = g_decode_A_info.nr_bytes2 + offset;
286 memcpy(g_decode_buffer2, &block[offset2], g_decode_A_info.nr_bytes2);
287
288
289 cprintf_field(" Word: ", "%d ", *(uint16_t *)&g_subblock_A[286]);
290 check_field(*(uint16_t *)&g_subblock_A[286], 1, "Ok\n", "Mismatch\n");
291
292 return 0;
293}
294
295static void decode_key_B(uint8_t buf[20], uint8_t buf2[16], uint8_t key[20])
296{
297 for(int i = 0; i < 20; i++)
298 {
299 uint8_t v = buf[i] ^ g_decode_B_table[i];
300 key[i] = v;
301 buf[i] = v ^ buf2[i % 16];
302 }
303}
304
305static void decode_block_B(uint8_t *buf, uint8_t key[16], size_t size)
306{
307 decode_key_B(&buf[size], key, g_key_B);
308 decode_block_with_perm(g_key_B, 20, buf, size, g_perm_B);
309}
310
311static int find_last_bit_set(uint32_t *buf, bool a)
312{
313 int i = a ? g_decode_A_info.nr_dwords_m1 : g_decode_A_info.nr_dwords_x2_m1;
314
315 while(i >= 0 && buf[i] == 0)
316 i--;
317 if(i < 0)
318 return -1;
319 for(int j = 31; j >= 0; j--)
320 if(buf[i] & (1 << j))
321 return 32 * i + j;
322 return -1; // unreachable
323}
324
325static void xor_with_ptrs(uint8_t *buf, ptr_bundle_t *ptrs)
326{
327 /*
328 int sz = g_decode_A_info.nr_bytes2 - 1;
329 if(sz <= 32)
330 {
331 for(int i = 0; i < sz; i++)
332 buf[i] ^= ptrs->ptrA[i];
333 for(int i = sz; i < 32; i++)
334 buf[i] ^= ptrs->ptrB[i - sz];
335 }
336 else
337 for(int i = 0; i < 32; i++)
338 buf[i] ^= ptrs->ptrA[i];
339 */
340 uint8_t *ptrA = (uint8_t *)ptrs->ptrA;
341 uint8_t *ptrB = (uint8_t *)ptrs->ptrB;
342 int sz = MIN(g_decode_A_info.nr_bytes2 - 1, 32);
343 for(int i = 0; i < sz; i++)
344 buf[i] ^= ptrA[i];
345 for(int i = sz; i < 32; i++)
346 buf[i] ^= ptrB[i - sz];
347}
348
349static void copy_memory(uint32_t *to, uint32_t *from)
350{
351 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
352 to[i] = from[i];
353}
354
355static void swap_memory(uint32_t *a, uint32_t *b)
356{
357 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
358 {
359 uint32_t c = a[i];
360 a[i] = b[i];
361 b[i] = c;
362 }
363}
364
365static void shift_left(uint32_t *buf, int nr_bits)
366{
367 for(int i = g_decode_A_info.nr_dwords_m1; i >= 0; i--)
368 buf[i + (nr_bits / 32)] = buf[i];
369 memset(buf, 0, 4 * (nr_bits / 32));
370
371 size_t size = g_decode_A_info.nr_dwords + (nr_bits + 31) / 32;
372 nr_bits = nr_bits % 32;
373
374 uint32_t acc = 0;
375 for(size_t i = 0; i < size; i++)
376 {
377 uint32_t new_val = buf[i] << nr_bits | acc;
378 /* WARNING if nr_bits = 0 then the right shift by 32 is undefined and so
379 * the following code could break. The additional AND catches this case
380 * and make sure the result is 0 */
381 acc = ((1 << nr_bits) - 1) & (buf[i] >> (32 - nr_bits));
382 buf[i] = new_val;
383 }
384}
385
386static void xor_big(uint32_t *res, uint32_t *a, uint32_t *b)
387{
388 for(int i = 0; i < g_decode_A_info.nr_dwords_x2; i++)
389 res[i] = a[i] ^ b[i];
390}
391
392static void decode_with_xor(uint32_t *res, uint32_t *key)
393{
394 uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8);
395 uint32_t *copy = malloc(g_decode_A_info.nr_dwords_x8);
396 uint32_t *copy_arg = malloc(g_decode_A_info.nr_dwords_x8);
397 uint32_t *tmp2 = malloc(g_decode_A_info.nr_dwords_x8);
398 clear_memory(tmp, g_decode_A_info.nr_dwords_x2);
399 clear_memory(res, g_decode_A_info.nr_dwords);
400 *res = 1;
401 clear_memory(tmp2, g_decode_A_info.nr_dwords);
402 copy_memory(copy_arg, key);
403 copy_memory(copy, (uint32_t *)g_decode_A_info.ptr5);
404
405 for(int i = find_last_bit_set(copy_arg, 1); i; i = find_last_bit_set(copy_arg, 1))
406 {
407 int pos = i - find_last_bit_set(copy, 1);
408 if(pos < 0)
409 {
410 swap_memory(copy_arg, copy);
411 swap_memory(res, tmp2);
412 pos = -pos;
413 }
414 copy_memory(tmp, copy);
415 shift_left(tmp, pos);
416 xor_big(copy_arg, copy_arg, tmp);
417 copy_memory(tmp, tmp2);
418 shift_left(tmp, pos);
419 xor_big(res, res, tmp);
420 }
421 free(tmp);
422 free(copy);
423 free(copy_arg);
424 free(tmp2);
425}
426
427static void shift_left_one(uint32_t *a)
428{
429 int pos = find_last_bit_set(a, 0) / 32 + 1;
430 if(pos <= 0)
431 return;
432 uint32_t v = 0;
433 for(int i = 0; i < pos; i++)
434 {
435 uint32_t new_val = v | a[i] << 1;
436 v = a[i] >> 31;
437 a[i] = new_val;
438 }
439 if(v)
440 a[pos] = v;
441}
442
443
444#if 1
445static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3)
446{
447 uint32_t *tmp2 = malloc(g_decode_A_info.nr_dwords_x8);
448 clear_memory(tmp2, g_decode_A_info.nr_dwords_x2);
449 copy_memory(tmp2, a3);
450
451 int pos = g_decode_A_info.nr_dwords;
452 uint32_t mask = 1;
453 for(int i = 0; i < 32; i++)
454 {
455 for(int j = 0; j < g_decode_A_info.nr_dwords; j++)
456 {
457 if(a2[j] & mask)
458 for(int k = 0; k < pos; k++)
459 a1[j + k] ^= tmp2[k];
460 }
461 shift_left_one(tmp2);
462 mask <<= 1;
463 pos = find_last_bit_set(tmp2, 0) / 32 + 1;
464 }
465 free(tmp2);
466}
467#else
468static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3)
469{
470 for(int i = 0; i < 32 * g_decode_A_info.nr_dwords; i++)
471 for(int j = 0; j < 32 * g_decode_A_info.nr_dwords; j++)
472 {
473 int k = i + j;
474 uint32_t v1 = (a2[i / 32] >> (i % 32)) & 1;
475 uint32_t v2 = (a3[j / 32] >> (j % 32)) & 1;
476 a1[k / 32] ^= (v1 * v2) << (k % 32);
477 }
478}
479#endif
480
481static void xor_mult_high(uint32_t *a1, uint32_t *buf, uint32_t *a3)
482{
483 (void) a1;
484 uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8);
485 int v4 = g_decode_A_info.field_34;
486 int pos = find_last_bit_set(buf, 0);
487 for(int i = pos - v4; i >= 0; i = find_last_bit_set(buf, 0) - v4)
488 {
489 clear_memory(tmp, g_decode_A_info.nr_dwords_x2);
490 copy_memory(tmp, a3);
491 shift_left(tmp, i);
492 xor_big(buf, buf, tmp);
493 }
494 free(tmp);
495}
496
497static void xor_small(uint32_t *res, uint32_t *a, uint32_t *b)
498{
499 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
500 res[i] = a[i] ^ b[i];
501}
502
503static void crypto(ptr_bundle_t *a1, ptr_bundle_t *a2)
504{
505 uint32_t *v2 = malloc(g_decode_A_info.nr_dwords_x8);
506 uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8);
507 uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8);
508 uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8);
509 uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8);
510 clear_memory(a2->ptrA, g_decode_A_info.nr_dwords);
511 clear_memory(a2->ptrB, g_decode_A_info.nr_dwords);
512 clear_memory(v3, g_decode_A_info.nr_dwords_x2);
513 clear_memory(v6, g_decode_A_info.nr_dwords_x2);
514 clear_memory(v4, g_decode_A_info.nr_dwords_x2);
515 decode_with_xor(v4, a1->ptrA);
516 clear_memory(v5, g_decode_A_info.nr_dwords_x2);
517
518 xor_mult(v5, v4, a1->ptrB);
519 xor_mult_high(v5, v5, g_decode_A_info.ptr5);
520 xor_small(v2, a1->ptrA, v5);
521 xor_small(v4, v2, g_decode_A_info.ptr6);
522 clear_memory(v3, g_decode_A_info.nr_dwords_x2);
523 xor_mult(v3, v2, v2);
524 xor_mult_high(v3, v3, g_decode_A_info.ptr5);
525 xor_small(a2->ptrA, v4, v3);
526 clear_memory(v5, g_decode_A_info.nr_dwords_x2);
527 xor_small(v4, v2, g_xor_key);
528 xor_mult(v5, v4, a2->ptrA);
529 xor_mult_high(v5, v5, g_decode_A_info.ptr5);
530 clear_memory(v6, g_decode_A_info.nr_dwords_x2);
531 xor_mult(v6, a1->ptrA, a1->ptrA);
532 xor_mult_high(v6, v6, g_decode_A_info.ptr5);
533 xor_small(a2->ptrB, v5, v6);
534 free(v2);
535 free(v3);
536 free(v4);
537 free(v5);
538 free(v6);
539}
540
541static void crypto2(ptr_bundle_t *a1, ptr_bundle_t *a2, ptr_bundle_t *a3)
542{
543 uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8);
544 uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8);
545 uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8);
546 uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8);
547 uint32_t *v7 = malloc(g_decode_A_info.nr_dwords_x8);
548 clear_memory(a3->ptrA, g_decode_A_info.nr_dwords);
549 clear_memory(a3->ptrB, g_decode_A_info.nr_dwords);
550 clear_memory(v4, g_decode_A_info.nr_dwords_x2);
551 clear_memory(v7, g_decode_A_info.nr_dwords_x2);
552 xor_small(v5, a1->ptrB, a2->ptrB);
553 xor_small(v6, a1->ptrA, a2->ptrA);
554 decode_with_xor(v7, v6);
555 clear_memory(v3, g_decode_A_info.nr_dwords_x2);
556 xor_mult(v3, v7, v5);
557 xor_mult_high(v3, v3, g_decode_A_info.ptr5);
558 xor_small(v5, v3, g_decode_A_info.ptr6);
559 clear_memory(v4, g_decode_A_info.nr_dwords_x2);
560 xor_mult(v4, v3, v3);
561 xor_mult_high(v4, v4, g_decode_A_info.ptr5);
562 xor_small(v7, v5, v4);
563 xor_small(a3->ptrA, v7, v6);
564 xor_small(v5, a1->ptrA, a3->ptrA);
565 xor_small(v6, a3->ptrA, a1->ptrB);
566 clear_memory(v7, g_decode_A_info.nr_dwords_x2);
567 xor_mult(v7, v5, v3);
568 xor_mult_high(v7, v7, g_decode_A_info.ptr5);
569 xor_small(a3->ptrB, v7, v6);
570 free(v3);
571 free(v4);
572 free(v5);
573 free(v6);
574 free(v7);
575}
576
577static int crypto3(uint32_t *a1, ptr_bundle_t *ptrs_alt, ptr_bundle_t *ptrs)
578{
579 ptr_bundle_t ptrs_others;
580
581 ptrs_others.ptrA = malloc(g_decode_A_info.size);
582 ptrs_others.ptrB = malloc(g_decode_A_info.size);
583 clear_memory(ptrs->ptrA, g_decode_A_info.nr_dwords);
584 clear_memory(ptrs->ptrB, g_decode_A_info.nr_dwords);
585 clear_memory(ptrs_others.ptrA, g_decode_A_info.nr_dwords);
586 clear_memory(ptrs_others.ptrB, g_decode_A_info.nr_dwords);
587 int pos = find_last_bit_set(a1, 1);
588
589 copy_memory(ptrs_others.ptrA, ptrs_alt->ptrA);
590 copy_memory(ptrs_others.ptrB, ptrs_alt->ptrB);
591 for(int bit = (pos % 32) - 1; bit >= 0; bit--)
592 {
593 crypto(&ptrs_others, ptrs);
594 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
595 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
596 if(a1[pos / 32] & (1 << bit))
597 {
598 crypto2(&ptrs_others, ptrs_alt, ptrs);
599 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
600 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
601 }
602 }
603 for(int i = pos / 32 - 1; i >= 0; i--)
604 {
605 for(int bit = 31; bit >= 0; bit--)
606 {
607 crypto(&ptrs_others, ptrs);
608 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
609 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
610 if(a1[i] & (1 << bit))
611 {
612 crypto2(&ptrs_others, ptrs_alt, ptrs);
613 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
614 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
615 }
616 }
617 }
618 copy_memory(ptrs->ptrA, ptrs_others.ptrA);
619 copy_memory(ptrs->ptrB, ptrs_others.ptrB);
620 free(ptrs_others.ptrA);
621 free(ptrs_others.ptrB);
622 return 0;
623}
624
625static int crypto4(uint8_t *a1, ptr_bundle_t *ptrs, uint32_t *a3)
626{
627 ptr_bundle_t ptrs_others;
628
629 ptrs_others.ptrA = malloc(g_decode_A_info.size);
630 ptrs_others.ptrB = malloc(g_decode_A_info.size);
631 clear_memory(ptrs_others.ptrA, g_decode_A_info.nr_dwords);
632 clear_memory(ptrs_others.ptrB, g_decode_A_info.nr_dwords);
633 int ret = crypto3(a3, ptrs, &ptrs_others);
634 if(ret == 0)
635 xor_with_ptrs(a1, &ptrs_others);
636 free(ptrs_others.ptrA);
637 free(ptrs_others.ptrB);
638 return ret;
639}
640
641static int crypto_bits(uint32_t *buf, int a2)
642{
643 clear_memory(buf, g_decode_A_info.nr_dwords);
644 g_decode_A_info.field_34 = 0;
645 if(a2 == 4)
646 {
647 set_bit(0, buf);
648 set_bit(74, buf);
649 set_bit(233, buf);
650 g_decode_A_info.field_34 = 233;
651 return 0;
652 }
653 else if (a2 == 5)
654 {
655 set_bit(0, buf);
656 set_bit(3, buf);
657 set_bit(6, buf);
658 set_bit(7, buf);
659 set_bit(163, buf);
660 g_decode_A_info.field_34 = 163;
661 return 0;
662 }
663 else
664 return 1;
665}
666
667static int crypto_bits_copy(ptr_bundle_t *a1, char a2)
668{
669 int ret = crypto_bits(g_decode_A_info.ptr5, a2);
670 if(ret) return ret;
671 if(a2 == 4)
672 {
673 copy_memory(a1->ptrA, g_crypto_table);
674 copy_memory(a1->ptrB, g_crypto_table2);
675 copy_memory(g_decode_A_info.ptr6, g_crypto_data);
676 copy_memory(g_decode_A_info.ptr7, g_crypto_key6);
677 return 0;
678 }
679 else if ( a2 == 5 )
680 {
681 copy_memory(a1->ptrA, g_crypto_key3);
682 copy_memory(a1->ptrB, g_crypto_key4);
683 copy_memory(g_decode_A_info.ptr6, g_crypto_data3);
684 copy_memory(g_decode_A_info.ptr7, g_crypto_key5);
685 return 0;
686 }
687 else
688 return 1;
689}
690
691static void create_guid(void *uid, int bit_size)
692{
693 uint8_t *p = uid;
694 for(int i = 0; i < bit_size / 8; i++)
695 p[i] = rand() % 256;
696}
697
698static int process_block_B(uint8_t block[512])
699{
700 cprintf(BLUE, "Block B\n");
701 decode_block_B(block + 3, g_subblock_A + 4, 489);
702 cprintf_field(" Word: ", "%d ", *(uint16_t *)(block + 3));
703 check_field(*(uint16_t *)(block + 3), 1, "Ok\n", "Mismatch\n");
704
705 int ret = check_block(block, block + 492, 492);
706 cprintf(GREEN, " Check: ");
707 check_field(ret, 0, "Pass\n", "Fail\n");
708
709 g_decode_buffer3 = malloc(g_decode_A_info.size);
710 memset(g_decode_buffer3, 0, g_decode_A_info.size);
711 int offset = *(uint16_t *)(block + 13) + 16;
712 memcpy(g_decode_buffer3, &block[offset], g_decode_A_info.nr_bytes2);
713
714 return 0;
715}
716
717static int get_key_fwu_v3(size_t size, uint8_t *buf, uint8_t *blockA, uint8_t *blockB,
718 uint8_t *keybuf, uint8_t *blo)
719{
720 (void) size;
721 uint8_t smallblock[512];
722 uint8_t bigblock[1024];
723
724 memset(smallblock, 0, sizeof(smallblock));
725 memset(bigblock, 0, sizeof(bigblock));
726
727 uint8_t ba = buf[0x1ee] & 0xf;
728 uint8_t bb = buf[0x1fe] & 0xf;
729
730 cprintf_field(" Block A: ", "%d\n", ba + 2);
731 cprintf_field(" Block B: ", "%d\n", ba + bb + 5);
732
733 *blockA = buf[494] & 0xf;
734 *blockB = buf[510] & 0xf;
735 memcpy(bigblock, &buf[512 * (*blockA + 2)], sizeof(bigblock));
736
737 int ret = process_block_A(bigblock);
738 if(ret != 0)
739 return ret;
740
741 memcpy(smallblock, &buf[512 * (*blockA + *blockB + 5)], sizeof(smallblock));
742 ret = process_block_B(smallblock);
743 if(ret != 0)
744 return ret;
745
746 cprintf(BLUE, "Main\n");
747
748 // WARNING you need more that 48 because 17+32 > 48 !! (see code below) */
749 uint8_t smallbuf[50];
750 memcpy(smallbuf, buf + 42, sizeof(smallbuf));
751 cprintf_field(" Byte: ", "%d ", smallbuf[16]);
752 check_field(smallbuf[16], 3, "Ok\n", "Mismatch\n");
753
754 ptr_bundle_t ptrs;
755 ptrs.ptrA = malloc(g_decode_A_info.size);
756 ptrs.ptrB = malloc(g_decode_A_info.size);
757 memset(ptrs.ptrA, 0, g_decode_A_info.size);
758 memset(ptrs.ptrB, 0, g_decode_A_info.size);
759 memcpy(ptrs.ptrA, buf + 91, g_decode_A_info.nr_bytes2);
760 memcpy(ptrs.ptrB, buf + 91 + g_decode_A_info.nr_bytes2, g_decode_A_info.nr_bytes2);
761
762 ret = crypto_bits_copy(&g_decode_A_info.ptr1, g_crypto_info_byte);
763 cprintf(GREEN, " Crypto bits copy: ");
764 check_field(ret, 0, "Pass\n", "Fail\n");
765
766 ret = crypto4(smallbuf + 17, &ptrs, g_decode_buffer3);
767 cprintf(GREEN, " Crypto 4: ");
768 check_field(ret, 0, "Pass\n", "Fail\n");
769
770 memcpy(keybuf, &smallbuf[17], 32);
771 int offset = g_decode_A_info.nr_words + 91;
772
773 decode_block_with_swap(keybuf, 0, &buf[offset], 512 - offset, g_perm_B);
774
775 int pos = *(uint16_t *)&buf[offset];
776 cprintf_field(" Word: ", "%d ", pos);
777 int tmp = g_decode_A_info.nr_words2 + 199;
778 check_field(pos, 510 - tmp, "Ok\n", "Mismatch\n");
779
780 uint8_t midbuf[108];
781 memcpy(midbuf, &buf[pos + offset + 2], sizeof(midbuf));
782
783 cprintf_field(" Byte: ", "%d ", midbuf[0]);
784 check_field(midbuf[0], 2, "Ok\n", "Invalid\n");
785 cprintf_field(" DWord: ", "%d ", *(uint32_t *)&midbuf[1]);
786 check_field(*(uint32_t *)&midbuf[1], 2056, "Ok\n", "Invalid\n");
787 cprintf_field(" DWord: ", "%d ", *(uint32_t *)&midbuf[5]);
788 check_field(*(uint32_t *)&midbuf[5], 8, "Ok\n", "Invalid\n");
789 cprintf_field(" Byte: ", "%d ", midbuf[41]);
790 check_field(midbuf[41], 190, "Ok\n", "Invalid\n");
791
792 memset(blo, 0, 512);
793 create_guid(smallblock, 3808);
794 memcpy(smallblock + 476, midbuf + 42, 16);
795 compute_checksum(smallblock, 492, blo + 492);
796 int bsz = blo[500];
797 memcpy(blo, smallblock, bsz);
798 memcpy(blo + bsz, midbuf + 42, 16);
799 memcpy(blo + bsz + 16, smallblock + bsz, 476 - bsz);
800
801 decode_block_with_perm(blo + 492, 16, blo, 492, g_perm_B);
802 ret = check_block(buf + 42, midbuf + 88, 450);
803 cprintf(GREEN, " Decode block: ");
804 check_field(ret, 0, "Pass\n", "Fail\n");
805
806 ret = memcmp(g_subblock_A + 4, midbuf + 9, 16);
807 cprintf(GREEN, " Compare: ");
808 check_field(ret, 0, "Pass\n", "Fail\n");
809
810 /*
811 ret = memcmp(midbuf + 25, zero, sizeof(zero));
812 cprintf(GREEN, " Sanity: ");
813 check_field(ret, 0, "Pass\n", "Fail\n");
814 */
815
816 return 0;
817}
818
819/* stolen from https://github.com/nfd/atj2127decrypt, I have no idea from where
820 * he got this sequence of code. This code is really weird, I copy verbatim
821 * his authors comment below. */
822uint32_t atj2127_key[] =
823{
824 0x42146ea2, 0x892c8e85, 0x9f9f6d27, 0x545fedc3,
825 0x09e5c0ca, 0x2dfa7e61, 0x4e5322e6, 0xb19185b9
826};
827
828/* decrypt a 512-byte sector */
829static void atj2127_decrypt_sector(void *inbuf, size_t size,
830 uint32_t session_key[8], int rounds_to_perform)
831{
832 uint32_t key[8];
833 for(int i = 0; i < 8; i++)
834 key[i] = atj2127_key[i] ^ session_key[i];
835 uint32_t *buf = inbuf;
836 if(size % 32)
837 cprintf(GREY, "Size is not a multiple of 32!!!\n");
838 while(rounds_to_perform > 0)
839 {
840 uint32_t rollover = buf[7] ^ session_key[7];
841
842 buf[0] ^= key[1];
843 buf[1] ^= key[2];
844 buf[2] ^= key[3];
845 buf[3] ^= key[4];
846 buf[4] ^= key[5];
847 buf[5] ^= key[6];
848 buf[6] ^= key[7];
849 buf[7] ^= key[1] ^ key[4];
850
851 key[1] = key[2];
852 key[2] = key[3];
853 key[3] = key[4];
854 key[4] = key[5];
855 key[5] = key[6];
856 key[6] = key[7];
857 key[7] = rollover;
858
859 buf += 8;
860 rounds_to_perform -= 1;
861 }
862}
863
864static void atj2127_decrypt(uint8_t *dst, const uint8_t *src, size_t size,
865 uint8_t keybuf[32], int rounds_to_perform)
866{
867 cprintf(BLUE, "ATJ2127:\n");
868 cprintf_field(" Rounds: ", "%d\n", rounds_to_perform);
869 while(size > 0)
870 {
871 int sec_sz = MIN(size, 512);
872 memcpy(dst, src, sec_sz);
873 atj2127_decrypt_sector(dst, sec_sz, (uint32_t *)keybuf, rounds_to_perform);
874 src += sec_sz;
875 dst += sec_sz;
876 size -= sec_sz;
877 }
878}
879
880static int decrypt_fwu_v3(uint8_t *buf, size_t *size, uint8_t block[512], enum fwu_mode_t mode)
881{
882 uint8_t blockA;
883 uint8_t blockB;
884 uint8_t keybuf[32];
885 memset(keybuf, 0, sizeof(keybuf));
886 int ret = get_key_fwu_v3(*size, buf, &blockA, &blockB, keybuf, block);
887 if(ret != 0)
888 return ret;
889
890 size_t file_size = *size;
891 /* the input buffer is reorganized based on two offsets (blockA and blockB),
892 * skip 2048 bytes of data used for crypto init */
893 *size -= 2048;
894 uint8_t *tmpbuf = malloc(*size);
895 memset(tmpbuf, 0, *size);
896 int offsetA = (blockA + 1) << 9;
897 int offsetB = (blockB + 1) << 9;
898 memcpy(tmpbuf, buf + 512, offsetA);
899 memcpy(tmpbuf + offsetA, buf + offsetA + 1536, offsetB);
900 memcpy(tmpbuf + offsetA + offsetB,
901 buf + offsetA + 1536 + offsetB + 512, *size - offsetA - offsetB);
902 /* stolen from https://github.com/nfd/atj2127decrypt, I have no idea from where
903 * he got this sequence of code. This code is really weird, I copy verbatim
904 * his authors comment below.
905 *
906 * This is really weird. This is passed to the decrypt-sector function and
907 * determines how much of each 512-byte sector to decrypt, where for every
908 * 32MB of size above the first 32MB, one 32 byte chunk of each sector
909 * (starting from the end) will remain unencrypted, up to a maximum of 480
910 * bytes of plaintext. Was this a speed-related thing? It just seems
911 * completely bizarre. */
912
913 /* NOTE: the original code uses the file length to determine how much
914 * to encrypt and not the size reported in the header. Since
915 * the file size can be different from the size reported in the header
916 * (the infamous 512 bytes described above), this might be wrong. */
917 int rounds_to_perform = 16 - (file_size >> 0x19);
918 if(rounds_to_perform <= 0)
919 rounds_to_perform = 1;
920 /* the ATJ213x and ATJ2127 do not use the same encryption at this point, and I
921 * don't see any obvious way to tell which encryption is used (since they
922 * use the same version above). The only difference is that ATJ2127 images
923 * I have seen have an extra 512 bytes at the end file (ie the actual file
924 * is 512 bytes larger than indicated by the header) but I don't know if this
925 * is the case for all files. Thus, unless the user force encryption mode,
926 * try both and see if one looks like an AFI file. To guess which one to use,
927 * decrypt the first sector and see if it looks like an AFI file */
928 bool is_atj2127 = false;
929 if(mode == FWU_AUTO)
930 {
931 uint8_t hdr_buf[512];
932 atj2127_decrypt(hdr_buf, tmpbuf, sizeof(hdr_buf), keybuf, rounds_to_perform);
933 is_atj2127 = afi_check(hdr_buf, sizeof(hdr_buf));
934 if(is_atj2127)
935 cprintf(BLUE, "File looks like an ATJ2127 firmware\n");
936 else
937 cprintf(BLUE, "File does not looks like an ATJ2127 firmware\n");
938 }
939 else if(mode == FWU_ATJ2127)
940 is_atj2127 = true;
941
942 if(is_atj2127)
943 atj2127_decrypt(buf, tmpbuf, *size, keybuf, rounds_to_perform);
944 else
945 {
946 compute_perm(keybuf, 32, g_perm_B);
947 decode_perm(tmpbuf, *size, g_perm_B);
948 memcpy(buf, tmpbuf, *size);
949 }
950
951 return 0;
952}
953
954int fwu_decrypt(uint8_t *buf, size_t *size, enum fwu_mode_t mode)
955{
956 struct fwu_hdr_t *hdr = (void *)buf;
957
958 if(*size < sizeof(struct fwu_hdr_t))
959 {
960 cprintf(GREY, "File too small\n");
961 return 1;
962 }
963 cprintf(BLUE, "Header\n");
964 cprintf(GREEN, " Signature:");
965 for(int i = 0; i < FWU_SIG_SIZE; i++)
966 cprintf(YELLOW, " %02x", hdr->sig[i]);
967 if(memcmp(hdr->sig, g_fwu_signature, FWU_SIG_SIZE) == 0)
968 cprintf(RED, " Ok\n");
969 else
970 {
971 cprintf(RED, " Mismatch\n");
972 return 1;
973 }
974
975 cprintf_field(" FW size: ", "%d ", hdr->fw_size);
976 if(hdr->fw_size == *size)
977 cprintf(RED, " Ok\n");
978 else if(hdr->fw_size < *size)
979 cprintf(RED, " Ok (file greater than firmware)\n");
980 else
981 {
982 cprintf(RED, " Error (file too small)\n");
983 return 1;
984 }
985
986 cprintf_field(" Block size: ", "%d ", hdr->block_size);
987 check_field(hdr->block_size, FWU_BLOCK_SIZE, "Ok\n", "Invalid\n");
988
989 cprintf_field(" Version: ", "%x ", hdr->version);
990 int ver = get_version(buf, *size);
991 if(ver < 0)
992 {
993 cprintf(RED, "(Unknown)\n");
994 return 1;
995 }
996 else
997 cprintf(RED, "(Ver. %d)\n", g_version[ver].version);
998
999 cprintf_field(" Unknown: ", "0x%x ", hdr->unk);
1000 check_field(hdr->unk, g_version[ver].unk, "Ok\n", "Invalid\n");
1001
1002 cprintf(GREEN, " Signature:");
1003 for(int i = 0; i < FWU_SIG_SIZE; i++)
1004 cprintf(YELLOW, " %02x", hdr->sig2[i]);
1005 if(memcmp(hdr->sig2, g_version[ver].sig2, FWU_SIG_SIZE) == 0)
1006 cprintf(RED, " Ok\n");
1007 else
1008 {
1009 cprintf(RED, " Mismatch\n");
1010 return 2;
1011 }
1012
1013 if(g_version[ver].version == 3)
1014 {
1015 uint8_t block[512];
1016 memset(block, 0, sizeof(block));
1017 return decrypt_fwu_v3(buf, size, block, mode);
1018 }
1019 else
1020 {
1021 cprintf(GREY, "Unsupported version: %d\n", g_version[ver].version);
1022 return 1;
1023 }
1024
1025}
1026
1027bool fwu_check(uint8_t *buf, size_t size)
1028{
1029 struct fwu_hdr_t *hdr = (void *)buf;
1030
1031 if(size < sizeof(struct fwu_hdr_t))
1032 return false;
1033 return memcmp(hdr->sig, g_fwu_signature, FWU_SIG_SIZE) == 0;
1034}
diff --git a/utils/atj2137/atjboottool/fwu.h b/utils/atj2137/atjboottool/fwu.h
new file mode 100644
index 0000000000..dc49d91df3
--- /dev/null
+++ b/utils/atj2137/atjboottool/fwu.h
@@ -0,0 +1,40 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2017 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __FWU_H__
22#define __FWU_H__
23
24#include <stdint.h>
25
26enum fwu_mode_t
27{
28 FWU_AUTO, /* Will try to guess which mode to use */
29 FWU_ATJ213X, /* Will use ATJ213x style mode */
30 FWU_ATJ2127, /* Will use ATJ2127 variation */
31};
32
33/* Decrypt a FWU file inplace, the size variable is updated to reflect the size of the decrypted
34 * firmware. Return 0 on success. The mode parameter selects how the function guesses between
35 * various variants of FWU. */
36int fwu_decrypt(uint8_t *buf, size_t *size, enum fwu_mode_t mode);
37/* Check if a file looks like a FWU file */
38bool fwu_check(uint8_t *buf, size_t size);
39
40#endif /* __FWU_H__ */
diff --git a/utils/atj2137/atjboottool/misc.c b/utils/atj2137/atjboottool/misc.c
index 108235e7fd..b13e4b4c5e 100644
--- a/utils/atj2137/atjboottool/misc.c
+++ b/utils/atj2137/atjboottool/misc.c
@@ -37,7 +37,12 @@ static bool g_color_enable = true;
37void *xmalloc(size_t s) 37void *xmalloc(size_t s)
38{ 38{
39 void * r = malloc(s); 39 void * r = malloc(s);
40 if(!r) bugp("malloc"); 40 if(!r)
41 {
42 color(GREY);
43 printf("Allocation failed.\n");
44 abort();
45 }
41 return r; 46 return r;
42} 47}
43 48
diff --git a/utils/atj2137/atjboottool/misc.h b/utils/atj2137/atjboottool/misc.h
index b0658c0d31..9248dba62c 100644
--- a/utils/atj2137/atjboottool/misc.h
+++ b/utils/atj2137/atjboottool/misc.h
@@ -22,14 +22,15 @@
22#define __MISC_H__ 22#define __MISC_H__
23 23
24#include <stdbool.h> 24#include <stdbool.h>
25#include <stdio.h>
25 26
26#define _STR(a) #a 27#define cprintf(col, ...) do {color(col); printf(__VA_ARGS__); }while(0)
27#define STR(a) _STR(a)
28 28
29#define bug(...) do { fprintf(stderr,"["__FILE__":"STR(__LINE__)"]ERROR: "__VA_ARGS__); exit(1); } while(0) 29#define cprintf_field(str1, ...) do{ cprintf(GREEN, str1); cprintf(YELLOW, __VA_ARGS__); }while(0)
30#define bugp(...) do { fprintf(stderr, __VA_ARGS__); perror(" "); exit(1); } while(0)
31 30
32#define ROUND_UP(val, round) ((((val) + (round) - 1) / (round)) * (round)) 31#ifndef MIN
32#define MIN(a,b) ((a) < (b) ? (a) : (b))
33#endif
33 34
34typedef char color_t[]; 35typedef char color_t[];
35 36