summaryrefslogtreecommitdiff
path: root/utils/atj2137/atjboottool/fwu.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/atj2137/atjboottool/fwu.c')
-rw-r--r--utils/atj2137/atjboottool/fwu.c1034
1 files changed, 1034 insertions, 0 deletions
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}