Prepare new maemo release
[maemo-rb.git] / utils / atj2137 / atjboottool / atjboottool.c
blob53b56a5d56993cf8848d25fe16f94d5ca856c1ed
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2012 Amaury Pouly
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include <stdio.h>
22 #include <stdint.h>
23 #include <stdbool.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <getopt.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include "misc.h"
30 #include "elf.h"
31 #include <sys/stat.h>
33 #ifndef MIN
34 #define MIN(a,b) ((a) < (b) ? (a) : (b))
35 #endif
37 #define cprintf(col, ...) do {color(col); printf(__VA_ARGS__); }while(0)
39 #define cprintf_field(str1, ...) do{ cprintf(GREEN, str1); cprintf(YELLOW, __VA_ARGS__); }while(0)
41 bool g_debug = false;
42 char *g_out_prefix = NULL;
43 char *g_in_file = NULL;
44 bool g_force = false;
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)
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); }
54 static void print_hex(void *p, int size, int unit)
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++)
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);
72 /**
73 * FWU
74 **/
76 #define FWU_SIG_SIZE 16
77 #define FWU_BLOCK_SIZE 512
79 struct fwu_hdr_t
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));
89 const uint8_t g_fwu_signature[FWU_SIG_SIZE] =
91 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x75
94 struct version_desc_t
96 uint8_t version;
97 uint8_t value;
98 uint8_t unk;
99 uint8_t sig2[FWU_SIG_SIZE];
102 struct version_desc_t g_version[] =
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 } },
109 #define NR_VERSIONS (int)(sizeof(g_version)/sizeof(g_version[0]))
111 typedef struct ptr_bundle_t
113 uint32_t *ptrA;
114 uint32_t *ptrB;
115 }ptr_bundle_t;
117 struct block_A_info_t
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;
144 struct block_A_info_t g_decode_A_info;
145 uint8_t g_subblock_A[0x128];
146 uint8_t g_key_B[20];
147 uint8_t g_perm_B[258];
148 uint8_t g_crypto_info_byte;
149 uint8_t *g_decode_buffer;
150 uint8_t *g_decode_buffer2;
151 void *g_decode_buffer3;
153 #include "atj_tables.h"
155 void compute_checksum(uint8_t *buf, int size, uint8_t t[20])
157 memset(t, 0, 20);
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];
165 int check_block(uint8_t *buf, uint8_t ref[20], unsigned size)
167 uint8_t t[20];
168 compute_checksum(buf, size, t);
170 return memcmp(ref, t, 20);
174 int get_version(uint8_t *buf, unsigned long size)
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;
184 static int decode_block_A(uint8_t block[1020])
186 uint8_t *p = &g_check_block_A_table[32 * (block[998] & 0x1f)];
187 uint8_t key[32];
189 for(int i = 0; i < 20; i++)
191 block[1000 + i] ^= p[i];
192 key[i] = block[1000 + i];
194 for(int i = 20; i < 32; i++)
195 key[i] = key[i - 20];
197 for(int i = 0; i < 992; i++)
198 block[i] ^= key[i % 32] ^ g_check_block_A_table[i];
200 return check_block(block - 1, block + 1000, 1001);
203 static void compute_perm(uint8_t *keybuf, int size, uint8_t perm[258])
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++)
211 uint8_t v = perm[i];
212 idx = (v + keybuf[i % size] + idx) % 256;
213 perm[i] = perm[idx];
214 perm[idx] = v;
218 static void decode_perm(uint8_t *buf, int size, uint8_t perm[258])
220 uint8_t idxa = perm[256];
221 uint8_t idxb = perm[257];
222 for(int i = 0; i < size; i++)
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];
233 static void decode_block_with_perm(uint8_t *keybuf, int keysize,
234 uint8_t *buf, int bufsize, uint8_t perm[258])
236 compute_perm(keybuf, keysize, perm);
237 decode_perm(buf, bufsize, perm);
240 static void apply_perm(uint8_t *inbuf, uint8_t *outbuf, int size, int swap)
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;
250 static void decode_block_with_swap(uint8_t keybuf[32], int swap,
251 uint8_t *buf, int bufsize, uint8_t perm[258])
253 uint8_t keybuf_interm[32];
255 apply_perm(keybuf, keybuf_interm, 32, swap);
256 decode_block_with_perm(keybuf_interm, 32, buf, bufsize, perm);
259 static void clear_memory(void *buf, int size_dwords)
261 memset(buf, 0, 4 * size_dwords);
264 static void set_bit(int bit_pos, uint32_t *buf)
266 buf[bit_pos / 32] |= 1 << (bit_pos % 32);
269 static int fill_decode_info(uint8_t sz)
271 if(sz == 2) sz = 233;
272 else if(sz == 3) sz = 163;
273 else return 1;
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);
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);
304 return 0;
307 static int process_block_A(uint8_t block[1024])
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");
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");
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);
325 memset(g_decode_buffer, 0, g_decode_A_info.size);
326 memset(g_decode_buffer2, 0, g_decode_A_info.size);
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);
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");
336 return 0;
339 static void decode_key_B(uint8_t buf[20], uint8_t buf2[16], uint8_t key[20])
341 for(int i = 0; i < 20; i++)
343 uint8_t v = buf[i] ^ g_decode_B_table[i];
344 key[i] = v;
345 buf[i] = v ^ buf2[i % 16];
349 static void decode_block_B(uint8_t *buf, uint8_t key[16], int size)
351 decode_key_B(&buf[size], key, g_key_B);
352 decode_block_with_perm(g_key_B, 20, buf, size, g_perm_B);
355 static int find_last_bit_set(uint32_t *buf, bool a)
357 int i = a ? g_decode_A_info.nr_dwords_m1 : g_decode_A_info.nr_dwords_x2_m1;
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
369 static void xor_with_ptrs(uint8_t *buf, ptr_bundle_t *ptrs)
372 int sz = g_decode_A_info.nr_bytes2 - 1;
373 if(sz <= 32)
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];
380 else
381 for(int i = 0; i < 32; i++)
382 buf[i] ^= ptrs->ptrA[i];
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];
393 static void copy_memory(uint32_t *to, uint32_t *from)
395 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
396 to[i] = from[i];
399 static void swap_memory(uint32_t *a, uint32_t *b)
401 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
403 uint32_t c = a[i];
404 a[i] = b[i];
405 b[i] = c;
409 static void shift_left(uint32_t *buf, int nr_bits)
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));
415 int size = g_decode_A_info.nr_dwords + (nr_bits + 31) / 32;
416 nr_bits = nr_bits % 32;
418 uint32_t acc = 0;
419 for(int i = 0; i < size; i++)
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;
430 static void xor_big(uint32_t *res, uint32_t *a, uint32_t *b)
432 for(int i = 0; i < g_decode_A_info.nr_dwords_x2; i++)
433 res[i] = a[i] ^ b[i];
436 static void decode_with_xor(uint32_t *res, uint32_t *key)
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);
449 for(int i = find_last_bit_set(copy_arg, 1); i; i = find_last_bit_set(copy_arg, 1))
451 int pos = i - find_last_bit_set(copy, 1);
452 if(pos < 0)
454 swap_memory(copy_arg, copy);
455 swap_memory(res, tmp2);
456 pos = -pos;
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);
465 free(tmp);
466 free(copy);
467 free(copy_arg);
468 free(tmp2);
471 static void shift_left_one(uint32_t *a)
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++)
479 uint32_t new_val = v | a[i] << 1;
480 v = a[i] >> 31;
481 a[i] = new_val;
483 if(v)
484 a[pos] = v;
488 #if 1
489 static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3)
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);
495 int pos = g_decode_A_info.nr_dwords;
496 uint32_t mask = 1;
497 for(int i = 0; i < 32; i++)
499 for(int j = 0; j < g_decode_A_info.nr_dwords; j++)
501 if(a2[j] & mask)
502 for(int k = 0; k < pos; k++)
503 a1[j + k] ^= tmp2[k];
505 shift_left_one(tmp2);
506 mask <<= 1;
507 pos = find_last_bit_set(tmp2, 0) / 32 + 1;
509 free(tmp2);
511 #else
512 static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3)
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++)
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);
523 #endif
525 static int compare(uint32_t *a, uint32_t *b)
527 return memcmp(a, b, g_decode_A_info.nr_dwords * 4);
530 static void xor_mult_high(uint32_t *a1, uint32_t *buf, uint32_t *a3)
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)
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);
543 free(tmp);
546 static void xor_small(uint32_t *res, uint32_t *a, uint32_t *b)
548 for(int i = 0; i < g_decode_A_info.nr_dwords; i++)
549 res[i] = a[i] ^ b[i];
552 static void crypto(ptr_bundle_t *a1, ptr_bundle_t *a2)
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);
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);
590 static void crypto2(ptr_bundle_t *a1, ptr_bundle_t *a2, ptr_bundle_t *a3)
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);
626 static int crypto3(uint32_t *a1, ptr_bundle_t *ptrs_alt, ptr_bundle_t *ptrs)
628 ptr_bundle_t ptrs_others;
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);
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--)
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))
647 crypto2(&ptrs_others, ptrs_alt, ptrs);
648 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
649 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
652 for(int i = pos / 32 - 1; i >= 0; i--)
654 for(int bit = 31; bit >= 0; bit--)
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))
661 crypto2(&ptrs_others, ptrs_alt, ptrs);
662 copy_memory(ptrs_others.ptrA, ptrs->ptrA);
663 copy_memory(ptrs_others.ptrB, ptrs->ptrB);
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;
674 static int crypto4(uint8_t *a1, ptr_bundle_t *ptrs, uint32_t *a3)
676 ptr_bundle_t ptrs_others;
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;
690 static int crypto_bits(uint32_t *buf, int a2)
692 clear_memory(buf, g_decode_A_info.nr_dwords);
693 g_decode_A_info.field_34 = 0;
694 if(a2 == 4)
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;
702 else if (a2 == 5)
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;
712 else
713 return 1;
716 static int crypto_bits_copy(ptr_bundle_t *a1, char a2)
718 int ret = crypto_bits(g_decode_A_info.ptr5, a2);
719 if(ret) return ret;
720 if(a2 == 4)
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;
728 else if ( a2 == 5 )
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;
736 else
737 return 1;
740 static void create_guid(void *uid, int bit_size)
742 uint8_t *p = uid;
743 for(int i = 0; i < bit_size / 8; i++)
744 p[i] = rand() % 256;
747 static int process_block_B(uint8_t block[512])
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");
754 int ret = check_block(block, block + 492, 492);
755 cprintf(GREEN, " Check: ");
756 check_field(ret, 0, "Pass\n", "Fail\n");
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);
763 return 0;
766 static int do_fwu_v3(int size, uint8_t *buf, uint8_t *blockA, uint8_t *blockB,
767 uint8_t *unk, uint8_t *unk2, uint8_t *blo)
769 (void) size;
770 uint8_t smallblock[512];
771 uint8_t bigblock[1024];
773 memset(smallblock, 0, sizeof(smallblock));
774 memset(bigblock, 0, sizeof(bigblock));
776 uint8_t ba = buf[0x1ee] & 0xf;
777 uint8_t bb = buf[0x1fe] & 0xf;
779 cprintf_field(" Block A: ", "%d\n", ba + 2);
780 cprintf(" Block B: ", "%d\n", ba + bb + 5);
782 *blockA = buf[494] & 0xf;
783 *blockB = buf[510] & 0xf;
784 memcpy(bigblock, &buf[512 * (*blockA + 2)], sizeof(bigblock));
786 int ret = process_block_A(bigblock);
787 continue_the_force(ret);
789 memcpy(smallblock, &buf[512 * (*blockA + *blockB + 5)], sizeof(smallblock));
790 ret = process_block_B(smallblock);
791 continue_the_force(ret);
793 cprintf(BLUE, "Main\n");
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");
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);
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");
813 ret = crypto4(smallbuf + 17, &ptrs, g_decode_buffer3);
814 cprintf(GREEN, " Crypto 4: ");
815 check_field(ret, 0, "Pass\n", "Fail\n");
817 memcpy(unk2, &smallbuf[17], 32);
818 int offset = g_decode_A_info.nr_words + 91;
820 decode_block_with_swap(unk2, 0, &buf[offset], 512 - offset, g_perm_B);
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");
827 uint8_t midbuf[108];
828 memcpy(midbuf, &buf[pos + offset + 2], sizeof(midbuf));
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");
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);
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");
853 ret = memcmp(g_subblock_A + 4, midbuf + 9, 16);
854 cprintf(GREEN, " Compare: ");
855 check_field(ret, 0, "Pass\n", "Fail\n");
857 uint8_t zero[16];
858 memset(zero, 0, sizeof(zero));
859 ret = memcmp(unk, zero, sizeof(zero));
860 cprintf(GREEN, " Sanity: ");
861 check_field(ret, 0, "Pass\n", "Fail\n");
864 ret = memcmp(midbuf + 25, zero, sizeof(zero));
865 cprintf(GREEN, " Sanity: ");
866 check_field(ret, 0, "Pass\n", "Fail\n");
869 return 0;
872 static int do_sthg_fwu_v3(uint8_t *buf, int *size, uint8_t *unk, uint8_t *block)
874 uint8_t blockA;
875 uint8_t blockB;
876 uint8_t unk2[32];
877 memset(unk2, 0, sizeof(unk2));
878 int ret = do_fwu_v3(*size, buf, &blockA, &blockB, unk, unk2, block);
879 continue_the_force(ret);
881 *size -= 2048;
882 uint8_t *tmpbuf = malloc(*size);
883 memset(tmpbuf, 0, *size);
884 int offsetA = (blockA + 1) << 9;
885 int offsetB = (blockB + 1) << 9;
886 memcpy(tmpbuf, buf + 512, offsetA);
887 memcpy(tmpbuf + offsetA, buf + offsetA + 1536, offsetB);
888 memcpy(tmpbuf + offsetA + offsetB,
889 buf + offsetA + 1536 + offsetB + 512, *size - offsetA - offsetB);
890 compute_perm(unk2, 32, g_perm_B);
891 decode_perm(tmpbuf, *size, g_perm_B);
892 memcpy(buf, tmpbuf, *size);
894 return 0;
897 /* [add]: string to add when there is no extension
898 * [replace]: string to replace extension */
899 static void build_out_prefix(char *add, char *replace, bool slash)
901 if(g_out_prefix)
902 return;
903 /** copy input filename with extra space */
904 g_out_prefix = malloc(strlen(g_in_file) + strlen(add) + 16);
905 strcpy(g_out_prefix, g_in_file);
906 /** remove extension and add '/' */
907 char *filename = strrchr(g_out_prefix, '/');
908 // have p points to the beginning or after the last '/'
909 filename = (filename == NULL) ? g_out_prefix : filename + 1;
910 // extension ?
911 char *dot = strrchr(filename, '.');
912 if(dot)
914 *dot = 0; // cut at the dot
915 strcat(dot, replace);
917 else
918 strcat(filename, add); // add extra string
920 if(slash)
922 strcat(filename, "/");
923 /** make sure the directory exists */
924 mkdir(g_out_prefix, S_IRWXU | S_IRGRP | S_IROTH);
928 static int do_fwu(uint8_t *buf, int size)
930 struct fwu_hdr_t *hdr = (void *)buf;
932 if(size < (int)sizeof(struct fwu_hdr_t))
934 cprintf(GREY, "File too small\n");
935 return 1;
937 cprintf(BLUE, "Header\n");
938 cprintf(GREEN, " Signature:");
939 for(int i = 0; i < FWU_SIG_SIZE; i++)
940 cprintf(YELLOW, " %02x", hdr->sig[i]);
941 if(memcmp(hdr->sig, g_fwu_signature, FWU_SIG_SIZE) == 0)
942 cprintf(RED, " Ok\n");
943 else
945 cprintf(RED, " Mismatch\n");
946 let_the_force_flow(__LINE__);
949 cprintf_field(" FW size: ", "%d ", hdr->fw_size);
950 if((int)hdr->fw_size == size)
951 cprintf(RED, " Ok\n");
952 else if((int)hdr->fw_size < size)
953 cprintf(RED, " Ok (file greater than firmware)\n");
954 else
956 cprintf(RED, " Error (file too small)\n");
957 let_the_force_flow(__LINE__);
960 cprintf_field(" Block size: ", "%d ", hdr->block_size);
961 check_field(hdr->block_size, FWU_BLOCK_SIZE, "Ok\n", "Invalid\n");
963 cprintf_field(" Version: ", "%x ", hdr->version);
964 int ver = get_version(buf, size);
965 if(ver < 0)
967 cprintf(RED, "(Unknown)\n");
968 return -1;
970 else
971 cprintf(RED, "(Ver. %d)\n", g_version[ver].version);
973 cprintf_field(" Unknown: ", "0x%x ", hdr->unk);
974 check_field(hdr->unk, g_version[ver].unk, "Ok\n", "Invalid\n");
976 cprintf(GREEN, " Signature:");
977 for(int i = 0; i < FWU_SIG_SIZE; i++)
978 cprintf(YELLOW, " %02x", hdr->sig2[i]);
979 if(memcmp(hdr->sig2, g_version[ver].sig2, FWU_SIG_SIZE) == 0)
980 cprintf(RED, " Ok\n");
981 else
983 cprintf(RED, " Mismatch\n");
984 let_the_force_flow(__LINE__);
987 build_out_prefix(".afi", ".afi", false);
989 if(g_version[ver].version == 3)
991 uint8_t unk[32];
992 memset(unk, 0, sizeof(unk));
993 uint8_t block[512];
994 memset(block, 0, sizeof(block));
995 int ret = do_sthg_fwu_v3(buf, &size, unk, block);
996 continue_the_force(ret);
998 cprintf(GREY, "Descrambling to %s... ", g_out_prefix);
999 FILE *f = fopen(g_out_prefix, "wb");
1000 if(f)
1002 fwrite(buf, size, 1, f);
1003 fclose(f);
1004 cprintf(RED, "Ok\n");
1006 else
1007 cprintf(RED, "Failed: %m\n");
1010 return 0;
1013 static bool check_fwu(uint8_t *buf, int size)
1015 struct fwu_hdr_t *hdr = (void *)buf;
1017 if(size < (int)sizeof(struct fwu_hdr_t))
1018 return false;
1019 return memcmp(hdr->sig, g_fwu_signature, FWU_SIG_SIZE) == 0;
1023 * AFI
1025 * part of this work comes from s1mp3/s1fwx
1028 #define AFI_ENTRIES 126
1029 #define AFI_SIG_SIZE 4
1031 struct afi_hdr_t
1033 uint8_t sig[AFI_SIG_SIZE];
1034 uint16_t vendor_id;
1035 uint16_t product_id;
1036 uint8_t ver_id[2];
1037 uint8_t ext_ver_id[2];
1038 uint8_t year[2];
1039 uint8_t month;
1040 uint8_t day;
1041 uint32_t afi_size;
1042 uint32_t res[3];
1043 } __attribute__((packed));
1045 struct afi_entry_t
1047 char name[8];
1048 char ext[3];
1049 char type;
1050 uint32_t addr;
1051 uint32_t offset;
1052 uint32_t size;
1053 char desc[4];
1054 uint32_t checksum;
1055 } __attribute__((packed));
1057 struct afi_post_hdr_t
1059 uint8_t res[28];
1060 uint32_t checksum;
1061 } __attribute__((packed));
1063 struct afi_t
1065 struct afi_hdr_t hdr;
1066 struct afi_entry_t entry[AFI_ENTRIES];
1067 struct afi_post_hdr_t post;
1070 #define AFI_ENTRY_BREC 'B'
1071 #define AFI_ENTRY_FWSC 'F'
1072 #define AFI_ENTRY_ADFUS 'A'
1073 #define AFI_ENTRY_FW 'I'
1075 #define AFI_ENTRY_DLADR_BREC 0x00000006 // 'B'
1076 #define AFI_ENTRY_DLADR_FWSC 0x00020008 // 'F'
1077 #define AFI_ENTRY_DLADR_ADFUS 0x000C0008 // 'A'
1078 #define AFI_ENTRY_DLADR_ADFU 0x00000000 // 'U'
1079 #define AFI_ENTRY_DLADR_FW 0x00000011 // 'I'
1081 const uint8_t g_afi_signature[AFI_SIG_SIZE] =
1083 'A', 'F', 'I', 0
1086 static uint32_t afi_checksum(void *ptr, int size)
1088 uint32_t crc = 0;
1089 uint32_t *cp = ptr;
1090 for(; size >= 4; size -= 4)
1091 crc += *cp++;
1092 if(size == 1)
1093 crc += *(uint8_t *)cp;
1094 else if(size == 2)
1095 crc += *(uint16_t *)cp;
1096 else if(size == 3)
1097 crc += *(uint16_t *)cp + ((*(uint8_t *)(cp + 2)) << 16);
1098 return crc;
1101 static void build_filename(char buf[16], struct afi_entry_t *ent)
1103 int pos = 0;
1104 for(int i = 0; i < 8 && ent->name[i] != ' '; i++)
1105 buf[pos++] = ent->name[i];
1106 buf[pos++] = '.';
1107 for(int i = 0; i < 3 && ent->ext[i] != ' '; i++)
1108 buf[pos++] = ent->ext[i];
1109 buf[pos] = 0;
1112 static int do_afi(uint8_t *buf, int size)
1114 struct afi_t *afi = (void *)buf;
1116 if(size < (int)sizeof(struct afi_t))
1118 cprintf(GREY, "File too small\n");
1119 return 1;
1121 cprintf(BLUE, "Header\n");
1122 cprintf(GREEN, " Signature:");
1123 for(int i = 0; i < AFI_SIG_SIZE; i++)
1124 cprintf(YELLOW, " %02x", afi->hdr.sig[i]);
1125 if(memcmp(afi->hdr.sig, g_afi_signature, AFI_SIG_SIZE) == 0)
1126 cprintf(RED, " Ok\n");
1127 else
1129 cprintf(RED, " Mismatch\n");
1130 let_the_force_flow(__LINE__);
1133 cprintf_field(" Vendor ID: ", "0x%x\n", afi->hdr.vendor_id);
1134 cprintf_field(" Product ID: ", "0x%x\n", afi->hdr.product_id);
1135 cprintf_field(" Version: ", "%x.%x\n", afi->hdr.ver_id[0], afi->hdr.ver_id[1]);
1136 cprintf_field(" Ext Version: ", "%x.%x\n", afi->hdr.ext_ver_id[0],
1137 afi->hdr.ext_ver_id[1]);
1138 cprintf_field(" Date: ", "%x/%x/%x%x\n", afi->hdr.day, afi->hdr.month,
1139 afi->hdr.year[0], afi->hdr.year[1]);
1141 cprintf_field(" AFI size: ", "%d ", afi->hdr.afi_size);
1142 if((int)afi->hdr.afi_size == size)
1143 cprintf(RED, " Ok\n");
1144 else if((int)afi->hdr.afi_size < size)
1145 cprintf(RED, " Ok (file greater than archive)\n");
1146 else
1148 cprintf(RED, " Error (file too small)\n");
1149 let_the_force_flow(__LINE__);
1152 cprintf_field(" Reserved: ", "%x %x %x\n", afi->hdr.res[0],
1153 afi->hdr.res[1], afi->hdr.res[2]);
1155 build_out_prefix(".fw", "", true);
1157 cprintf(BLUE, "Entries\n");
1158 for(int i = 0; i < AFI_ENTRIES; i++)
1160 if(afi->entry[i].name[0] == 0)
1161 continue;
1162 struct afi_entry_t *entry = &afi->entry[i];
1163 char filename[16];
1164 build_filename(filename, entry);
1165 cprintf(RED, " %s\n", filename);
1166 cprintf_field(" Type: ", "%02x", entry->type);
1167 if(isprint(entry->type))
1168 cprintf(RED, " %c", entry->type);
1169 printf("\n");
1170 cprintf_field(" Addr: ", "0x%x\n", entry->addr);
1171 cprintf_field(" Offset: ", "0x%x\n", entry->offset);
1172 cprintf_field(" Size: ", "0x%x\n", entry->size);
1173 cprintf_field(" Desc: ", "%.4s\n", entry->desc);
1174 cprintf_field(" Checksum: ", "0x%x ", entry->checksum);
1175 uint32_t chk = afi_checksum(buf + entry->offset, entry->size);
1176 cprintf(RED, "%s\n", chk == entry->checksum ? "Ok" : "Mismatch");
1178 char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16);
1179 sprintf(name, "%s%s", g_out_prefix, filename);
1181 cprintf(GREY, "Unpacking to %s... ", name);
1182 FILE *f = fopen(name, "wb");
1183 if(f)
1185 fwrite(buf + entry->offset, entry->size, 1, f);
1186 fclose(f);
1187 cprintf(RED, "Ok\n");
1189 else
1190 cprintf(RED, "Failed: %m\n");
1193 cprintf(BLUE, "Post Header\n");
1194 cprintf_field(" Checksum: ", "%x ", afi->post.checksum);
1195 uint32_t chk = afi_checksum(buf, sizeof(struct afi_t) - 4);
1196 cprintf(RED, "%s\n", chk == afi->post.checksum ? "Ok" : "Mismatch");
1198 return 0;
1201 static bool check_afi(uint8_t *buf, int size)
1203 struct afi_hdr_t *hdr = (void *)buf;
1205 if(size < (int)sizeof(struct afi_hdr_t))
1206 return false;
1207 return memcmp(hdr->sig, g_afi_signature, AFI_SIG_SIZE) == 0;
1211 * FW
1214 #define FW_SIG_SIZE 4
1216 #define FW_ENTRIES 240
1218 struct fw_entry_t
1220 char name[8];
1221 char ext[3];
1222 uint8_t attr;
1223 uint8_t res[2];
1224 uint16_t version;
1225 uint32_t block_offset; // offset shift by 9
1226 uint32_t size;
1227 uint32_t unk;
1228 uint32_t checksum;
1229 } __attribute__((packed));
1231 struct fw_hdr_t
1233 uint8_t sig[FW_SIG_SIZE];
1234 uint32_t res[4];
1235 uint8_t year[2];
1236 uint8_t month;
1237 uint8_t day;
1238 uint16_t usb_vid;
1239 uint16_t usb_pid;
1240 uint32_t checksum;
1241 char productor[16];
1242 char str2[16];
1243 char str3[32];
1244 char dev_name[32];
1245 uint8_t res2[8 * 16];
1246 char usb_name1[8];
1247 char usb_name2[8];
1248 char res3[4 * 16 + 1];
1249 char mtp_name1[33];
1250 char mtp_name2[33];
1251 char mtp_ver[33];
1252 uint16_t mtp_vid;
1253 uint16_t mtp_pid;
1254 char fw_ver[64];
1255 uint32_t res4[2];
1257 struct fw_entry_t entry[FW_ENTRIES];
1258 } __attribute__((packed));
1260 const uint8_t g_fw_signature[FW_SIG_SIZE] =
1262 0x55, 0xaa, 0xf2, 0x0f
1265 static void build_filename_fw(char buf[16], struct fw_entry_t *ent)
1267 int pos = 0;
1268 for(int i = 0; i < 8 && ent->name[i] != ' '; i++)
1269 buf[pos++] = ent->name[i];
1270 buf[pos++] = '.';
1271 for(int i = 0; i < 3 && ent->ext[i] != ' '; i++)
1272 buf[pos++] = ent->ext[i];
1273 buf[pos] = 0;
1276 static int do_fw(uint8_t *buf, int size)
1278 struct fw_hdr_t *hdr = (void *)buf;
1280 if(size < (int)sizeof(struct fw_hdr_t))
1282 cprintf(GREY, "File too small\n");
1283 return 1;
1285 cprintf(BLUE, "Header\n");
1286 cprintf(GREEN, " Signature:");
1287 for(int i = 0; i < FW_SIG_SIZE; i++)
1288 cprintf(YELLOW, " %02x", hdr->sig[i]);
1289 if(memcmp(hdr->sig, g_fw_signature, FW_SIG_SIZE) == 0)
1290 cprintf(RED, " Ok\n");
1291 else
1293 cprintf(RED, " Mismatch\n");
1294 let_the_force_flow(__LINE__);
1297 cprintf_field(" USB VID: ", "0x%x\n", hdr->usb_vid);
1298 cprintf_field(" USB PID: ", "0x%x\n", hdr->usb_pid);
1299 cprintf_field(" Date: ", "%x/%x/%x%x\n", hdr->day, hdr->month, hdr->year[0], hdr->year[1]);
1300 cprintf_field(" Checksum: ", "%x\n", hdr->checksum);
1301 cprintf_field(" Productor: ", "%.16s\n", hdr->productor);
1302 cprintf_field(" String 2: ", "%.16s\n", hdr->str2);
1303 cprintf_field(" String 3: ", "%.32s\n", hdr->str3);
1304 cprintf_field(" Device Name: ", "%.32s\n", hdr->dev_name);
1305 cprintf(GREEN, " Unknown:\n");
1306 for(int i = 0; i < 8; i++)
1308 cprintf(YELLOW, " ");
1309 for(int j = 0; j < 16; j++)
1310 cprintf(YELLOW, "%02x ", hdr->res2[i * 16 + j]);
1311 cprintf(YELLOW, "\n");
1313 cprintf_field(" USB Name 1: ", "%.8s\n", hdr->usb_name1);
1314 cprintf_field(" USB Name 2: ", "%.8s\n", hdr->usb_name2);
1315 cprintf_field(" MTP Name 1: ", "%.32s\n", hdr->mtp_name1);
1316 cprintf_field(" MTP Name 2: ", "%.32s\n", hdr->mtp_name2);
1317 cprintf_field(" MTP Version: ", "%.32s\n", hdr->mtp_ver);
1319 cprintf_field(" MTP VID: ", "0x%x\n", hdr->mtp_vid);
1320 cprintf_field(" MTP PID: ", "0x%x\n", hdr->mtp_pid);
1321 cprintf_field(" FW Version: ", "%.64s\n", hdr->fw_ver);
1323 build_out_prefix(".unpack", "", true);
1325 cprintf(BLUE, "Entries\n");
1326 for(int i = 0; i < AFI_ENTRIES; i++)
1328 if(hdr->entry[i].name[0] == 0)
1329 continue;
1330 struct fw_entry_t *entry = &hdr->entry[i];
1331 char filename[16];
1332 build_filename_fw(filename, entry);
1333 cprintf(RED, " %s\n", filename);
1334 cprintf_field(" Attr: ", "%02x\n", entry->attr);
1335 cprintf_field(" Offset: ", "0x%x\n", entry->block_offset << 9);
1336 cprintf_field(" Size: ", "0x%x\n", entry->size);
1337 cprintf_field(" Unknown: ", "%x\n", entry->unk);
1338 cprintf_field(" Checksum: ", "0x%x ", entry->checksum);
1339 uint32_t chk = afi_checksum(buf + (entry->block_offset << 9), entry->size);
1340 cprintf(RED, "%s\n", chk == entry->checksum ? "Ok" : "Mismatch");
1341 if(g_out_prefix)
1343 char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16);
1344 sprintf(name, "%s%s", g_out_prefix, filename);
1346 cprintf(GREY, "Unpacking to %s... ", name);
1347 FILE *f = fopen(name, "wb");
1348 if(f)
1350 fwrite(buf + (entry->block_offset << 9), entry->size, 1, f);
1351 fclose(f);
1352 cprintf(RED, "Ok\n");
1354 else
1355 cprintf(RED, "Failed: %m\n");
1359 return 0;
1362 static bool check_fw(uint8_t *buf, int size)
1364 struct fw_hdr_t *hdr = (void *)buf;
1366 if(size < (int)sizeof(struct fw_hdr_t))
1367 return false;
1368 return memcmp(hdr->sig, g_fw_signature, FW_SIG_SIZE) == 0;
1371 static void usage(void)
1373 printf("Usage: atjboottool [options] firmware\n");
1374 printf("Options:\n");
1375 printf(" -o <prefix>\tSet output prefix\n");
1376 printf(" -f/--force\tForce to continue on errors\n");
1377 printf(" -?/--help\tDisplay this message\n");
1378 printf(" -d/--debug\tDisplay debug messages\n");
1379 printf(" -c/--no-color\tDisable color output\n");
1380 printf(" --fwu\tUnpack a FWU firmware file\n");
1381 printf(" --afi\tUnpack a AFI archive file\n");
1382 printf(" --fw\tUnpack a FW archive file\n");
1383 printf("The default is to try to guess the format.\n");
1384 printf("If several formats are specified, all are tried.\n");
1385 printf("If no output prefix is specified, a default one is picked.\n");
1386 exit(1);
1389 int main(int argc, char **argv)
1391 bool try_fwu = false;
1392 bool try_afi = false;
1393 bool try_fw = false;
1395 while(1)
1397 static struct option long_options[] =
1399 {"help", no_argument, 0, '?'},
1400 {"debug", no_argument, 0, 'd'},
1401 {"no-color", no_argument, 0, 'c'},
1402 {"force", no_argument, 0, 'f'},
1403 {"fwu", no_argument, 0, 'u'},
1404 {"afi", no_argument, 0, 'a'},
1405 {"fw", no_argument, 0, 'w'},
1406 {0, 0, 0, 0}
1409 int c = getopt_long(argc, argv, "?dcfo:a1", long_options, NULL);
1410 if(c == -1)
1411 break;
1412 switch(c)
1414 case -1:
1415 break;
1416 case 'c':
1417 enable_color(false);
1418 break;
1419 case 'd':
1420 g_debug = true;
1421 break;
1422 case 'f':
1423 g_force = true;
1424 break;
1425 case '?':
1426 usage();
1427 break;
1428 case 'o':
1429 g_out_prefix = optarg;
1430 break;
1431 case 'a':
1432 try_afi = true;
1433 break;
1434 case 'u':
1435 try_fwu = true;
1436 break;
1437 case 'w':
1438 try_fw = true;
1439 break;
1440 default:
1441 abort();
1445 if(argc - optind != 1)
1447 usage();
1448 return 1;
1451 g_in_file = argv[optind];
1452 FILE *fin = fopen(g_in_file, "r");
1453 if(fin == NULL)
1455 perror("Cannot open boot file");
1456 return 1;
1458 fseek(fin, 0, SEEK_END);
1459 long size = ftell(fin);
1460 fseek(fin, 0, SEEK_SET);
1462 void *buf = malloc(size);
1463 if(buf == NULL)
1465 perror("Cannot allocate memory");
1466 return 1;
1469 if(fread(buf, size, 1, fin) != 1)
1471 perror("Cannot read file");
1472 return 1;
1475 fclose(fin);
1477 int ret = -99;
1478 if(try_fwu || check_fwu(buf, size))
1479 ret = do_fwu(buf, size);
1480 else if(try_afi || check_afi(buf, size))
1481 ret = do_afi(buf, size);
1482 else if(try_fw || check_fw(buf, size))
1483 ret = do_fw(buf, size);
1484 else
1486 cprintf(GREY, "No valid format found\n");
1487 ret = 1;
1490 if(ret != 0)
1492 cprintf(GREY, "Error: %d", ret);
1493 if(!g_force)
1494 cprintf(GREY, " (use --force to force processing)");
1495 printf("\n");
1496 ret = 2;
1498 free(buf);
1500 color(OFF);
1502 return ret;