diff options
Diffstat (limited to 'utils/atj2137/atjboottool')
-rw-r--r-- | utils/atj2137/atjboottool/atj_tables.c | 9 | ||||
-rw-r--r-- | utils/atj2137/atjboottool/atj_tables.h | 5 | ||||
-rw-r--r-- | utils/atj2137/atjboottool/fwu.c | 431 |
3 files changed, 264 insertions, 181 deletions
diff --git a/utils/atj2137/atjboottool/atj_tables.c b/utils/atj2137/atjboottool/atj_tables.c index ab3444cbaa..579e17d52b 100644 --- a/utils/atj2137/atjboottool/atj_tables.c +++ b/utils/atj2137/atjboottool/atj_tables.c | |||
@@ -109,11 +109,6 @@ uint8_t g_decode_B_table[20] = | |||
109 | 0xf8, 0xb4, 0x36, 0x41, 0xc5, 0x51, 0xaf | 109 | 0xf8, 0xb4, 0x36, 0x41, 0xc5, 0x51, 0xaf |
110 | }; | 110 | }; |
111 | 111 | ||
112 | uint32_t g_xor_key[9] = | ||
113 | { | ||
114 | 1, 0, 0, 0, 0, 0, 0, 0, 0 | ||
115 | }; | ||
116 | |||
117 | uint32_t g_crypto_table[8] = | 112 | uint32_t g_crypto_table[8] = |
118 | { | 113 | { |
119 | 0xefad6126, 0x0a4c9d6e, 0x19c26bf5, 0x149563a4, 0x29f22ff4, 0x7e731af1, | 114 | 0xefad6126, 0x0a4c9d6e, 0x19c26bf5, 0x149563a4, 0x29f22ff4, 0x7e731af1, |
@@ -142,7 +137,7 @@ uint32_t g_crypto_key4[6] = | |||
142 | 0x797324f1, 0xb11c5c0c, 0xa2cdd545, 0x71a0094f, 0xd51fbc6c, 0x00000000 | 137 | 0x797324f1, 0xb11c5c0c, 0xa2cdd545, 0x71a0094f, 0xd51fbc6c, 0x00000000 |
143 | }; | 138 | }; |
144 | 139 | ||
145 | uint32_t g_crypto_data3[6] = | 140 | uint32_t g_atj_ec163_a[6] = |
146 | { | 141 | { |
147 | 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 | 142 | 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
148 | }; | 143 | }; |
@@ -152,7 +147,7 @@ uint32_t g_crypto_key5[6] = | |||
152 | 0x4a3205fd, 0x512f7874, 0x1481eb10, 0xb8c953ca, 0x0a601907, 0x00000002 | 147 | 0x4a3205fd, 0x512f7874, 0x1481eb10, 0xb8c953ca, 0x0a601907, 0x00000002 |
153 | }; | 148 | }; |
154 | 149 | ||
155 | uint32_t g_crypto_data[8] = | 150 | uint32_t g_atj_ec233_a[8] = |
156 | { | 151 | { |
157 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 152 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
158 | }; | 153 | }; |
diff --git a/utils/atj2137/atjboottool/atj_tables.h b/utils/atj2137/atjboottool/atj_tables.h index 5daa66fec3..d5eb4ae5d4 100644 --- a/utils/atj2137/atjboottool/atj_tables.h +++ b/utils/atj2137/atjboottool/atj_tables.h | |||
@@ -23,14 +23,13 @@ | |||
23 | 23 | ||
24 | uint8_t g_check_block_A_table[1024]; | 24 | uint8_t g_check_block_A_table[1024]; |
25 | uint8_t g_decode_B_table[20]; | 25 | uint8_t g_decode_B_table[20]; |
26 | uint32_t g_xor_key[9]; | ||
27 | uint32_t g_crypto_table[8]; | 26 | uint32_t g_crypto_table[8]; |
28 | uint32_t g_crypto_table2[8]; | 27 | uint32_t g_crypto_table2[8]; |
29 | uint32_t g_crypto_key6[8]; | 28 | uint32_t g_crypto_key6[8]; |
30 | uint32_t g_crypto_key3[6]; | 29 | uint32_t g_crypto_key3[6]; |
31 | uint32_t g_crypto_key4[6]; | 30 | uint32_t g_crypto_key4[6]; |
32 | uint32_t g_crypto_key5[6]; | 31 | uint32_t g_crypto_key5[6]; |
33 | uint32_t g_crypto_data[8]; | 32 | uint32_t g_atj_ec233_a[8]; |
34 | uint32_t g_crypto_data3[6]; | 33 | uint32_t g_atj_ec163_a[6]; |
35 | 34 | ||
36 | #endif // __ATJ_TABLES__ | 35 | #endif // __ATJ_TABLES__ |
diff --git a/utils/atj2137/atjboottool/fwu.c b/utils/atj2137/atjboottool/fwu.c index 82ef28632a..4d09dd876e 100644 --- a/utils/atj2137/atjboottool/fwu.c +++ b/utils/atj2137/atjboottool/fwu.c | |||
@@ -52,6 +52,13 @@ const uint8_t g_fwu_signature[FWU_SIG_SIZE] = | |||
52 | 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x75 | 52 | 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x75 |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct fwu_crypto_hdr_t | ||
56 | { | ||
57 | uint8_t field0[16]; | ||
58 | uint8_t unk; | ||
59 | uint8_t key[32]; | ||
60 | } __attribute__((packed)); | ||
61 | |||
55 | struct fwu_tail_t | 62 | struct fwu_tail_t |
56 | { | 63 | { |
57 | uint8_t length; /* in blocks? it's always 1 */ | 64 | uint8_t length; /* in blocks? it's always 1 */ |
@@ -82,11 +89,11 @@ struct version_desc_t g_version[] = | |||
82 | 89 | ||
83 | #define NR_VERSIONS (int)(sizeof(g_version)/sizeof(g_version[0])) | 90 | #define NR_VERSIONS (int)(sizeof(g_version)/sizeof(g_version[0])) |
84 | 91 | ||
85 | typedef struct ptr_bundle_t | 92 | typedef struct ec_point_t |
86 | { | 93 | { |
87 | uint32_t *ptrA; | 94 | uint32_t *x; |
88 | uint32_t *ptrB; | 95 | uint32_t *y; |
89 | }ptr_bundle_t; | 96 | }ec_point_t; |
90 | 97 | ||
91 | struct block_A_info_t | 98 | struct block_A_info_t |
92 | { | 99 | { |
@@ -94,16 +101,16 @@ struct block_A_info_t | |||
94 | uint16_t field_2; | 101 | uint16_t field_2; |
95 | int nr_words; | 102 | int nr_words; |
96 | int nr_dwords_x12; | 103 | int nr_dwords_x12; |
97 | uint32_t *ptr6; // size | 104 | uint32_t *ec_a; // size |
98 | uint32_t *ptr7; // size | 105 | uint32_t *ptr7; // size |
99 | uint32_t *ptr5; // size | 106 | uint32_t *field_poly; // size |
100 | uint32_t size; | 107 | uint32_t size; |
101 | uint32_t field_1C; | 108 | uint32_t field_1C; |
102 | ptr_bundle_t ptr1; | 109 | ec_point_t ptr1; |
103 | uint32_t *ptr3; // size | 110 | uint32_t *ptr3; // size |
104 | uint32_t *ptr4; // size | 111 | uint32_t *ptr4; // size |
105 | int nr_words2; | 112 | int nr_words2; |
106 | uint32_t field_34; | 113 | uint32_t field_bits; |
107 | int nr_dwords_x8; | 114 | int nr_dwords_x8; |
108 | int nr_bytes; | 115 | int nr_bytes; |
109 | int nr_bytes2; | 116 | int nr_bytes2; |
@@ -125,6 +132,28 @@ uint8_t *g_decode_buffer2; | |||
125 | void *g_decode_buffer3; | 132 | void *g_decode_buffer3; |
126 | 133 | ||
127 | #include "atj_tables.h" | 134 | #include "atj_tables.h" |
135 | #include <ctype.h> | ||
136 | |||
137 | void print_hex(const char *name, void *buf, size_t sz) | ||
138 | { | ||
139 | if(name) | ||
140 | cprintf(BLUE, "%s\n", name); | ||
141 | uint8_t *p = buf; | ||
142 | for(size_t i = 0; i < sz; i += 16) | ||
143 | { | ||
144 | if(name) | ||
145 | cprintf(OFF, " "); | ||
146 | for(size_t j = i; j < i + 16; j++) | ||
147 | if(j < sz) | ||
148 | cprintf(YELLOW, "%02x ", p[j]); | ||
149 | else | ||
150 | cprintf(OFF, " "); | ||
151 | cprintf(RED, " |"); | ||
152 | for(size_t j = i; j < i + 16; j++) | ||
153 | cprintf(GREEN, "%c", (j < sz && isprint(p[j])) ? p[j] : '.'); | ||
154 | cprintf(RED, "|\n"); | ||
155 | } | ||
156 | } | ||
128 | 157 | ||
129 | void compute_checksum(uint8_t *buf, size_t size, uint8_t t[20]) | 158 | void compute_checksum(uint8_t *buf, size_t size, uint8_t t[20]) |
130 | { | 159 | { |
@@ -258,12 +287,12 @@ static int fill_decode_info(uint8_t sz) | |||
258 | g_decode_A_info.nr_dwords_x2 = 2 * g_decode_A_info.nr_dwords; | 287 | g_decode_A_info.nr_dwords_x2 = 2 * g_decode_A_info.nr_dwords; |
259 | g_decode_A_info.nr_dwords_x2_m1 = g_decode_A_info.nr_dwords_x2 - 1; | 288 | g_decode_A_info.nr_dwords_x2_m1 = g_decode_A_info.nr_dwords_x2 - 1; |
260 | g_decode_A_info.nr_dwords_x12 = 12 * g_decode_A_info.nr_dwords; | 289 | g_decode_A_info.nr_dwords_x12 = 12 * g_decode_A_info.nr_dwords; |
261 | g_decode_A_info.ptr1.ptrA = malloc(4 * g_decode_A_info.nr_dwords); | 290 | g_decode_A_info.ptr1.x = malloc(4 * g_decode_A_info.nr_dwords); |
262 | g_decode_A_info.ptr1.ptrB = malloc(g_decode_A_info.size); | 291 | g_decode_A_info.ptr1.y = malloc(g_decode_A_info.size); |
263 | g_decode_A_info.ptr3 = malloc(g_decode_A_info.size); | 292 | g_decode_A_info.ptr3 = malloc(g_decode_A_info.size); |
264 | g_decode_A_info.ptr4 = malloc(g_decode_A_info.size); | 293 | g_decode_A_info.ptr4 = malloc(g_decode_A_info.size); |
265 | g_decode_A_info.ptr5 = malloc(g_decode_A_info.size); | 294 | g_decode_A_info.field_poly = malloc(g_decode_A_info.size); |
266 | g_decode_A_info.ptr6 = malloc(g_decode_A_info.size); | 295 | g_decode_A_info.ec_a = malloc(g_decode_A_info.size); |
267 | g_decode_A_info.ptr7 = malloc(g_decode_A_info.size); | 296 | g_decode_A_info.ptr7 = malloc(g_decode_A_info.size); |
268 | 297 | ||
269 | cprintf(BLUE, " Decode Info:\n"); | 298 | cprintf(BLUE, " Decode Info:\n"); |
@@ -284,6 +313,7 @@ static int process_block_A(uint8_t block[1024]) | |||
284 | int ret = decode_block_A(block + 4); | 313 | int ret = decode_block_A(block + 4); |
285 | cprintf(GREEN, " Check: "); | 314 | cprintf(GREEN, " Check: "); |
286 | check_field(ret, 0, "Pass\n", "Fail\n"); | 315 | check_field(ret, 0, "Pass\n", "Fail\n"); |
316 | print_hex("BlockA", block, 1024); | ||
287 | 317 | ||
288 | memcpy(g_subblock_A, block, sizeof(g_subblock_A)); | 318 | memcpy(g_subblock_A, block, sizeof(g_subblock_A)); |
289 | ret = fill_decode_info(g_subblock_A[276]); | 319 | ret = fill_decode_info(g_subblock_A[276]); |
@@ -340,30 +370,6 @@ static int find_last_bit_set(uint32_t *buf, bool a) | |||
340 | return -1; // unreachable | 370 | return -1; // unreachable |
341 | } | 371 | } |
342 | 372 | ||
343 | static void xor_with_ptrs(uint8_t *buf, ptr_bundle_t *ptrs) | ||
344 | { | ||
345 | /* | ||
346 | int sz = g_decode_A_info.nr_bytes2 - 1; | ||
347 | if(sz <= 32) | ||
348 | { | ||
349 | for(int i = 0; i < sz; i++) | ||
350 | buf[i] ^= ptrs->ptrA[i]; | ||
351 | for(int i = sz; i < 32; i++) | ||
352 | buf[i] ^= ptrs->ptrB[i - sz]; | ||
353 | } | ||
354 | else | ||
355 | for(int i = 0; i < 32; i++) | ||
356 | buf[i] ^= ptrs->ptrA[i]; | ||
357 | */ | ||
358 | uint8_t *ptrA = (uint8_t *)ptrs->ptrA; | ||
359 | uint8_t *ptrB = (uint8_t *)ptrs->ptrB; | ||
360 | int sz = MIN(g_decode_A_info.nr_bytes2 - 1, 32); | ||
361 | for(int i = 0; i < sz; i++) | ||
362 | buf[i] ^= ptrA[i]; | ||
363 | for(int i = sz; i < 32; i++) | ||
364 | buf[i] ^= ptrB[i - sz]; | ||
365 | } | ||
366 | |||
367 | static void copy_memory(uint32_t *to, uint32_t *from) | 373 | static void copy_memory(uint32_t *to, uint32_t *from) |
368 | { | 374 | { |
369 | for(int i = 0; i < g_decode_A_info.nr_dwords; i++) | 375 | for(int i = 0; i < g_decode_A_info.nr_dwords; i++) |
@@ -407,7 +413,27 @@ static void xor_big(uint32_t *res, uint32_t *a, uint32_t *b) | |||
407 | res[i] = a[i] ^ b[i]; | 413 | res[i] = a[i] ^ b[i]; |
408 | } | 414 | } |
409 | 415 | ||
410 | static void decode_with_xor(uint32_t *res, uint32_t *key) | 416 | static void print_poly(const char *name, uint32_t *poly, int nr_dwords) |
417 | { | ||
418 | bool first = true; | ||
419 | cprintf(RED, "%s", name); | ||
420 | for(int dw = 0; dw < nr_dwords; dw++) | ||
421 | { | ||
422 | for(int i = 0; i < 32; i++) | ||
423 | { | ||
424 | if(!(poly[dw] & (1 << i))) | ||
425 | continue; | ||
426 | if(first) | ||
427 | first = false; | ||
428 | else | ||
429 | cprintf(OFF, "+"); | ||
430 | cprintf(OFF, "x^%d", dw * 32 + i); | ||
431 | } | ||
432 | } | ||
433 | cprintf(OFF, "\n"); | ||
434 | } | ||
435 | |||
436 | static void gf_inverse(uint32_t *res, uint32_t *val) | ||
411 | { | 437 | { |
412 | uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8); | 438 | uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8); |
413 | uint32_t *copy = malloc(g_decode_A_info.nr_dwords_x8); | 439 | uint32_t *copy = malloc(g_decode_A_info.nr_dwords_x8); |
@@ -417,8 +443,8 @@ static void decode_with_xor(uint32_t *res, uint32_t *key) | |||
417 | clear_memory(res, g_decode_A_info.nr_dwords); | 443 | clear_memory(res, g_decode_A_info.nr_dwords); |
418 | *res = 1; | 444 | *res = 1; |
419 | clear_memory(tmp2, g_decode_A_info.nr_dwords); | 445 | clear_memory(tmp2, g_decode_A_info.nr_dwords); |
420 | copy_memory(copy_arg, key); | 446 | copy_memory(copy_arg, val); |
421 | copy_memory(copy, (uint32_t *)g_decode_A_info.ptr5); | 447 | copy_memory(copy, (uint32_t *)g_decode_A_info.field_poly); |
422 | 448 | ||
423 | for(int i = find_last_bit_set(copy_arg, 1); i; i = find_last_bit_set(copy_arg, 1)) | 449 | for(int i = find_last_bit_set(copy_arg, 1); i; i = find_last_bit_set(copy_arg, 1)) |
424 | { | 450 | { |
@@ -460,7 +486,7 @@ static void shift_left_one(uint32_t *a) | |||
460 | 486 | ||
461 | 487 | ||
462 | #if 1 | 488 | #if 1 |
463 | static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) | 489 | static void gf_mult(uint32_t *res, uint32_t *a2, uint32_t *a3) |
464 | { | 490 | { |
465 | uint32_t *tmp2 = malloc(g_decode_A_info.nr_dwords_x8); | 491 | uint32_t *tmp2 = malloc(g_decode_A_info.nr_dwords_x8); |
466 | clear_memory(tmp2, g_decode_A_info.nr_dwords_x2); | 492 | clear_memory(tmp2, g_decode_A_info.nr_dwords_x2); |
@@ -474,7 +500,7 @@ static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) | |||
474 | { | 500 | { |
475 | if(a2[j] & mask) | 501 | if(a2[j] & mask) |
476 | for(int k = 0; k < pos; k++) | 502 | for(int k = 0; k < pos; k++) |
477 | a1[j + k] ^= tmp2[k]; | 503 | res[j + k] ^= tmp2[k]; |
478 | } | 504 | } |
479 | shift_left_one(tmp2); | 505 | shift_left_one(tmp2); |
480 | mask <<= 1; | 506 | mask <<= 1; |
@@ -483,7 +509,7 @@ static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) | |||
483 | free(tmp2); | 509 | free(tmp2); |
484 | } | 510 | } |
485 | #else | 511 | #else |
486 | static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) | 512 | static void gf_mult(uint32_t *res, uint32_t *a2, uint32_t *a3) |
487 | { | 513 | { |
488 | for(int i = 0; i < 32 * g_decode_A_info.nr_dwords; i++) | 514 | for(int i = 0; i < 32 * g_decode_A_info.nr_dwords; i++) |
489 | for(int j = 0; j < 32 * g_decode_A_info.nr_dwords; j++) | 515 | for(int j = 0; j < 32 * g_decode_A_info.nr_dwords; j++) |
@@ -491,64 +517,84 @@ static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) | |||
491 | int k = i + j; | 517 | int k = i + j; |
492 | uint32_t v1 = (a2[i / 32] >> (i % 32)) & 1; | 518 | uint32_t v1 = (a2[i / 32] >> (i % 32)) & 1; |
493 | uint32_t v2 = (a3[j / 32] >> (j % 32)) & 1; | 519 | uint32_t v2 = (a3[j / 32] >> (j % 32)) & 1; |
494 | a1[k / 32] ^= (v1 * v2) << (k % 32); | 520 | res[k / 32] ^= (v1 * v2) << (k % 32); |
495 | } | 521 | } |
496 | } | 522 | } |
497 | #endif | 523 | #endif |
498 | 524 | ||
499 | static void xor_mult_high(uint32_t *a1, uint32_t *buf, uint32_t *a3) | 525 | static void gf_mod(uint32_t *inout, uint32_t *other) |
500 | { | 526 | { |
501 | (void) a1; | ||
502 | uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8); | 527 | uint32_t *tmp = malloc(g_decode_A_info.nr_dwords_x8); |
503 | int v4 = g_decode_A_info.field_34; | 528 | int v4 = g_decode_A_info.field_bits; |
504 | int pos = find_last_bit_set(buf, 0); | 529 | int pos = find_last_bit_set(inout, 0); |
505 | for(int i = pos - v4; i >= 0; i = find_last_bit_set(buf, 0) - v4) | 530 | for(int i = pos - v4; i >= 0; i = find_last_bit_set(inout, 0) - v4) |
506 | { | 531 | { |
507 | clear_memory(tmp, g_decode_A_info.nr_dwords_x2); | 532 | clear_memory(tmp, g_decode_A_info.nr_dwords_x2); |
508 | copy_memory(tmp, a3); | 533 | copy_memory(tmp, other); |
509 | shift_left(tmp, i); | 534 | shift_left(tmp, i); |
510 | xor_big(buf, buf, tmp); | 535 | xor_big(inout, inout, tmp); |
511 | } | 536 | } |
512 | free(tmp); | 537 | free(tmp); |
513 | } | 538 | } |
514 | 539 | ||
515 | static void xor_small(uint32_t *res, uint32_t *a, uint32_t *b) | 540 | static void gf_add(uint32_t *res, uint32_t *a, uint32_t *b) |
516 | { | 541 | { |
517 | for(int i = 0; i < g_decode_A_info.nr_dwords; i++) | 542 | for(int i = 0; i < g_decode_A_info.nr_dwords; i++) |
518 | res[i] = a[i] ^ b[i]; | 543 | res[i] = a[i] ^ b[i]; |
519 | } | 544 | } |
520 | 545 | ||
521 | static void crypto(ptr_bundle_t *a1, ptr_bundle_t *a2) | 546 | static void print_point(const char *name, ec_point_t *ptr) |
547 | { | ||
548 | cprintf(BLUE, "%s\n", name); | ||
549 | print_poly(" x: ", ptr->x, g_decode_A_info.nr_dwords); | ||
550 | print_poly(" y: ", ptr->y, g_decode_A_info.nr_dwords); | ||
551 | } | ||
552 | |||
553 | static uint32_t g_gf_one[9] = | ||
554 | { | ||
555 | 1, 0, 0, 0, 0, 0, 0, 0, 0 | ||
556 | }; | ||
557 | |||
558 | static void ec_double(ec_point_t *point, ec_point_t *res) | ||
522 | { | 559 | { |
523 | uint32_t *v2 = malloc(g_decode_A_info.nr_dwords_x8); | 560 | uint32_t *v2 = malloc(g_decode_A_info.nr_dwords_x8); |
524 | uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8); | 561 | uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8); |
525 | uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8); | 562 | uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8); |
526 | uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8); | 563 | uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8); |
527 | uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8); | 564 | uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8); |
528 | clear_memory(a2->ptrA, g_decode_A_info.nr_dwords); | 565 | clear_memory(res->x, g_decode_A_info.nr_dwords); |
529 | clear_memory(a2->ptrB, g_decode_A_info.nr_dwords); | 566 | clear_memory(res->y, g_decode_A_info.nr_dwords); |
530 | clear_memory(v3, g_decode_A_info.nr_dwords_x2); | 567 | clear_memory(v3, g_decode_A_info.nr_dwords_x2); |
531 | clear_memory(v6, g_decode_A_info.nr_dwords_x2); | 568 | clear_memory(v6, g_decode_A_info.nr_dwords_x2); |
532 | clear_memory(v4, g_decode_A_info.nr_dwords_x2); | 569 | clear_memory(v4, g_decode_A_info.nr_dwords_x2); |
533 | decode_with_xor(v4, a1->ptrA); | 570 | /* v4 := 1/x */ |
571 | gf_inverse(v4, point->x); | ||
534 | clear_memory(v5, g_decode_A_info.nr_dwords_x2); | 572 | clear_memory(v5, g_decode_A_info.nr_dwords_x2); |
535 | 573 | /* v5 := y/x */ | |
536 | xor_mult(v5, v4, a1->ptrB); | 574 | gf_mult(v5, v4, point->y); |
537 | xor_mult_high(v5, v5, g_decode_A_info.ptr5); | 575 | gf_mod(v5, g_decode_A_info.field_poly); |
538 | xor_small(v2, a1->ptrA, v5); | 576 | /* v2 := x + y/x (lambda) */ |
539 | xor_small(v4, v2, g_decode_A_info.ptr6); | 577 | gf_add(v2, point->x, v5); |
578 | /* v4 := ec_a + lambda */ | ||
579 | gf_add(v4, v2, g_decode_A_info.ec_a); | ||
540 | clear_memory(v3, g_decode_A_info.nr_dwords_x2); | 580 | clear_memory(v3, g_decode_A_info.nr_dwords_x2); |
541 | xor_mult(v3, v2, v2); | 581 | /* v3 := lambda^2 */ |
542 | xor_mult_high(v3, v3, g_decode_A_info.ptr5); | 582 | gf_mult(v3, v2, v2); |
543 | xor_small(a2->ptrA, v4, v3); | 583 | gf_mod(v3, g_decode_A_info.field_poly); |
584 | /* x' := lambda + lambda^2 + ec_a */ | ||
585 | gf_add(res->x, v4, v3); | ||
544 | clear_memory(v5, g_decode_A_info.nr_dwords_x2); | 586 | clear_memory(v5, g_decode_A_info.nr_dwords_x2); |
545 | xor_small(v4, v2, g_xor_key); | 587 | /* v4 := lambda + g_gf_one */ |
546 | xor_mult(v5, v4, a2->ptrA); | 588 | gf_add(v4, v2, g_gf_one); |
547 | xor_mult_high(v5, v5, g_decode_A_info.ptr5); | 589 | /* v5 := (lambda + 1) * x' = lambda.x' + x' */ |
590 | gf_mult(v5, v4, res->x); | ||
591 | gf_mod(v5, g_decode_A_info.field_poly); | ||
548 | clear_memory(v6, g_decode_A_info.nr_dwords_x2); | 592 | clear_memory(v6, g_decode_A_info.nr_dwords_x2); |
549 | xor_mult(v6, a1->ptrA, a1->ptrA); | 593 | /* v6 := x1^2 */ |
550 | xor_mult_high(v6, v6, g_decode_A_info.ptr5); | 594 | gf_mult(v6, point->x, point->x); |
551 | xor_small(a2->ptrB, v5, v6); | 595 | gf_mod(v6, g_decode_A_info.field_poly); |
596 | /* y' = (lambda + g_gf_one) * x + x^2 = x^2 + lambda.x + x */ | ||
597 | gf_add(res->y, v5, v6); | ||
552 | free(v2); | 598 | free(v2); |
553 | free(v3); | 599 | free(v3); |
554 | free(v4); | 600 | free(v4); |
@@ -556,35 +602,47 @@ static void crypto(ptr_bundle_t *a1, ptr_bundle_t *a2) | |||
556 | free(v6); | 602 | free(v6); |
557 | } | 603 | } |
558 | 604 | ||
559 | static void crypto2(ptr_bundle_t *a1, ptr_bundle_t *a2, ptr_bundle_t *a3) | 605 | static void ec_add(ec_point_t *a1, ec_point_t *a2, ec_point_t *res) |
560 | { | 606 | { |
561 | uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8); | 607 | uint32_t *v3 = malloc(g_decode_A_info.nr_dwords_x8); |
562 | uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8); | 608 | uint32_t *v4 = malloc(g_decode_A_info.nr_dwords_x8); |
563 | uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8); | 609 | uint32_t *v5 = malloc(g_decode_A_info.nr_dwords_x8); |
564 | uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8); | 610 | uint32_t *v6 = malloc(g_decode_A_info.nr_dwords_x8); |
565 | uint32_t *v7 = malloc(g_decode_A_info.nr_dwords_x8); | 611 | uint32_t *v7 = malloc(g_decode_A_info.nr_dwords_x8); |
566 | clear_memory(a3->ptrA, g_decode_A_info.nr_dwords); | 612 | clear_memory(res->x, g_decode_A_info.nr_dwords); |
567 | clear_memory(a3->ptrB, g_decode_A_info.nr_dwords); | 613 | clear_memory(res->y, g_decode_A_info.nr_dwords); |
568 | clear_memory(v4, g_decode_A_info.nr_dwords_x2); | 614 | clear_memory(v4, g_decode_A_info.nr_dwords_x2); |
569 | clear_memory(v7, g_decode_A_info.nr_dwords_x2); | 615 | clear_memory(v7, g_decode_A_info.nr_dwords_x2); |
570 | xor_small(v5, a1->ptrB, a2->ptrB); | 616 | /* v5 = y1 + y2 */ |
571 | xor_small(v6, a1->ptrA, a2->ptrA); | 617 | gf_add(v5, a1->y, a2->y); |
572 | decode_with_xor(v7, v6); | 618 | /* v6 = x1 + x2 */ |
619 | gf_add(v6, a1->x, a2->x); | ||
620 | /* v7 = 1/(x1 + x2) */ | ||
621 | gf_inverse(v7, v6); | ||
573 | clear_memory(v3, g_decode_A_info.nr_dwords_x2); | 622 | clear_memory(v3, g_decode_A_info.nr_dwords_x2); |
574 | xor_mult(v3, v7, v5); | 623 | /* v3 = (y1 + y2) / (x1 + x2) (lambda) */ |
575 | xor_mult_high(v3, v3, g_decode_A_info.ptr5); | 624 | gf_mult(v3, v7, v5); |
576 | xor_small(v5, v3, g_decode_A_info.ptr6); | 625 | gf_mod(v3, g_decode_A_info.field_poly); |
626 | /* v5 = lambda + ec_a */ | ||
627 | gf_add(v5, v3, g_decode_A_info.ec_a); | ||
577 | clear_memory(v4, g_decode_A_info.nr_dwords_x2); | 628 | clear_memory(v4, g_decode_A_info.nr_dwords_x2); |
578 | xor_mult(v4, v3, v3); | 629 | /* v4 = lambda^2 */ |
579 | xor_mult_high(v4, v4, g_decode_A_info.ptr5); | 630 | gf_mult(v4, v3, v3); |
580 | xor_small(v7, v5, v4); | 631 | gf_mod(v4, g_decode_A_info.field_poly); |
581 | xor_small(a3->ptrA, v7, v6); | 632 | /* v7 = lambda^2 + lambda + ec_a */ |
582 | xor_small(v5, a1->ptrA, a3->ptrA); | 633 | gf_add(v7, v5, v4); |
583 | xor_small(v6, a3->ptrA, a1->ptrB); | 634 | /* x' = ec_a + x1 + x2 + lambda + lambda^2 */ |
635 | gf_add(res->x, v7, v6); | ||
636 | /* v5 = x1 + x' */ | ||
637 | gf_add(v5, a1->x, res->x); | ||
638 | /* v6 = x' + y1 */ | ||
639 | gf_add(v6, res->x, a1->y); | ||
584 | clear_memory(v7, g_decode_A_info.nr_dwords_x2); | 640 | clear_memory(v7, g_decode_A_info.nr_dwords_x2); |
585 | xor_mult(v7, v5, v3); | 641 | /* v7 = (x1 + x').lambda */ |
586 | xor_mult_high(v7, v7, g_decode_A_info.ptr5); | 642 | gf_mult(v7, v5, v3); |
587 | xor_small(a3->ptrB, v7, v6); | 643 | gf_mod(v7, g_decode_A_info.field_poly); |
644 | /* y' = (x1 + x').lambda + x' + y1 */ | ||
645 | gf_add(res->y, v7, v6); | ||
588 | free(v3); | 646 | free(v3); |
589 | free(v4); | 647 | free(v4); |
590 | free(v5); | 648 | free(v5); |
@@ -592,113 +650,145 @@ static void crypto2(ptr_bundle_t *a1, ptr_bundle_t *a2, ptr_bundle_t *a3) | |||
592 | free(v7); | 650 | free(v7); |
593 | } | 651 | } |
594 | 652 | ||
595 | static int crypto3(uint32_t *a1, ptr_bundle_t *ptrs_alt, ptr_bundle_t *ptrs) | 653 | static int ec_mult(uint32_t *n, ec_point_t *point, ec_point_t *res) |
596 | { | 654 | { |
597 | ptr_bundle_t ptrs_others; | 655 | ec_point_t res_others; |
598 | 656 | ||
599 | ptrs_others.ptrA = malloc(g_decode_A_info.size); | 657 | res_others.x = malloc(g_decode_A_info.size); |
600 | ptrs_others.ptrB = malloc(g_decode_A_info.size); | 658 | res_others.y = malloc(g_decode_A_info.size); |
601 | clear_memory(ptrs->ptrA, g_decode_A_info.nr_dwords); | 659 | clear_memory(res->x, g_decode_A_info.nr_dwords); |
602 | clear_memory(ptrs->ptrB, g_decode_A_info.nr_dwords); | 660 | clear_memory(res->y, g_decode_A_info.nr_dwords); |
603 | clear_memory(ptrs_others.ptrA, g_decode_A_info.nr_dwords); | 661 | clear_memory(res_others.x, g_decode_A_info.nr_dwords); |
604 | clear_memory(ptrs_others.ptrB, g_decode_A_info.nr_dwords); | 662 | clear_memory(res_others.y, g_decode_A_info.nr_dwords); |
605 | int pos = find_last_bit_set(a1, 1); | 663 | int pos = find_last_bit_set(n, 1); |
606 | 664 | ||
607 | copy_memory(ptrs_others.ptrA, ptrs_alt->ptrA); | 665 | /* res_other := point */ |
608 | copy_memory(ptrs_others.ptrB, ptrs_alt->ptrB); | 666 | copy_memory(res_others.x, point->x); |
667 | copy_memory(res_others.y, point->y); | ||
668 | |||
669 | /* for all bit from SZ-1 downto 0 */ | ||
609 | for(int bit = (pos % 32) - 1; bit >= 0; bit--) | 670 | for(int bit = (pos % 32) - 1; bit >= 0; bit--) |
610 | { | 671 | { |
611 | crypto(&ptrs_others, ptrs); | 672 | /* res := 2 * res_other */ |
612 | copy_memory(ptrs_others.ptrA, ptrs->ptrA); | 673 | ec_double(&res_others, res); |
613 | copy_memory(ptrs_others.ptrB, ptrs->ptrB); | 674 | /* res_other := res = 2 * res_other */ |
614 | if(a1[pos / 32] & (1 << bit)) | 675 | copy_memory(res_others.x, res->x); |
676 | copy_memory(res_others.y, res->y); | ||
677 | /* if bit of n is set */ | ||
678 | if(n[pos / 32] & (1 << bit)) | ||
615 | { | 679 | { |
616 | crypto2(&ptrs_others, ptrs_alt, ptrs); | 680 | /* res := res_other + point */ |
617 | copy_memory(ptrs_others.ptrA, ptrs->ptrA); | 681 | ec_add(&res_others, point, res); |
618 | copy_memory(ptrs_others.ptrB, ptrs->ptrB); | 682 | copy_memory(res_others.x, res->x); |
683 | copy_memory(res_others.y, res->y); | ||
619 | } | 684 | } |
620 | } | 685 | } |
686 | /* same but optimized */ | ||
621 | for(int i = pos / 32 - 1; i >= 0; i--) | 687 | for(int i = pos / 32 - 1; i >= 0; i--) |
622 | { | 688 | { |
623 | for(int bit = 31; bit >= 0; bit--) | 689 | for(int bit = 31; bit >= 0; bit--) |
624 | { | 690 | { |
625 | crypto(&ptrs_others, ptrs); | 691 | ec_double(&res_others, res); |
626 | copy_memory(ptrs_others.ptrA, ptrs->ptrA); | 692 | copy_memory(res_others.x, res->x); |
627 | copy_memory(ptrs_others.ptrB, ptrs->ptrB); | 693 | copy_memory(res_others.y, res->y); |
628 | if(a1[i] & (1 << bit)) | 694 | if(n[i] & (1 << bit)) |
629 | { | 695 | { |
630 | crypto2(&ptrs_others, ptrs_alt, ptrs); | 696 | ec_add(&res_others, point, res); |
631 | copy_memory(ptrs_others.ptrA, ptrs->ptrA); | 697 | copy_memory(res_others.x, res->x); |
632 | copy_memory(ptrs_others.ptrB, ptrs->ptrB); | 698 | copy_memory(res_others.y, res->y); |
633 | } | 699 | } |
634 | } | 700 | } |
635 | } | 701 | } |
636 | copy_memory(ptrs->ptrA, ptrs_others.ptrA); | 702 | copy_memory(res->x, res_others.x); |
637 | copy_memory(ptrs->ptrB, ptrs_others.ptrB); | 703 | copy_memory(res->y, res_others.y); |
638 | free(ptrs_others.ptrA); | 704 | free(res_others.x); |
639 | free(ptrs_others.ptrB); | 705 | free(res_others.y); |
640 | return 0; | 706 | return 0; |
641 | } | 707 | } |
642 | 708 | ||
643 | static int crypto4(uint8_t *a1, ptr_bundle_t *ptrs, uint32_t *a3) | 709 | static void xor_with_point(uint8_t *buf, ec_point_t *point) |
644 | { | 710 | { |
645 | ptr_bundle_t ptrs_others; | 711 | /* |
712 | int sz = g_decode_A_info.nr_bytes2 - 1; | ||
713 | if(sz <= 32) | ||
714 | { | ||
715 | for(int i = 0; i < sz; i++) | ||
716 | buf[i] ^= point->x[i]; | ||
717 | for(int i = sz; i < 32; i++) | ||
718 | buf[i] ^= point->y[i - sz]; | ||
719 | } | ||
720 | else | ||
721 | for(int i = 0; i < 32; i++) | ||
722 | buf[i] ^= point->x[i]; | ||
723 | */ | ||
724 | uint8_t *ptrA = (uint8_t *)point->x; | ||
725 | uint8_t *ptrB = (uint8_t *)point->y; | ||
726 | int sz = MIN(g_decode_A_info.nr_bytes2 - 1, 32); | ||
727 | for(int i = 0; i < sz; i++) | ||
728 | buf[i] ^= ptrA[i]; | ||
729 | for(int i = sz; i < 32; i++) | ||
730 | buf[i] ^= ptrB[i - sz]; | ||
731 | } | ||
732 | |||
733 | static int crypto4(uint8_t *a1, ec_point_t *ptrs, uint32_t *a3) | ||
734 | { | ||
735 | ec_point_t ptrs_others; | ||
646 | 736 | ||
647 | ptrs_others.ptrA = malloc(g_decode_A_info.size); | 737 | ptrs_others.x = malloc(g_decode_A_info.size); |
648 | ptrs_others.ptrB = malloc(g_decode_A_info.size); | 738 | ptrs_others.y = malloc(g_decode_A_info.size); |
649 | clear_memory(ptrs_others.ptrA, g_decode_A_info.nr_dwords); | 739 | clear_memory(ptrs_others.x, g_decode_A_info.nr_dwords); |
650 | clear_memory(ptrs_others.ptrB, g_decode_A_info.nr_dwords); | 740 | clear_memory(ptrs_others.y, g_decode_A_info.nr_dwords); |
651 | int ret = crypto3(a3, ptrs, &ptrs_others); | 741 | int ret = ec_mult(a3, ptrs, &ptrs_others); |
652 | if(ret == 0) | 742 | if(ret == 0) |
653 | xor_with_ptrs(a1, &ptrs_others); | 743 | xor_with_point(a1, &ptrs_others); |
654 | free(ptrs_others.ptrA); | 744 | free(ptrs_others.x); |
655 | free(ptrs_others.ptrB); | 745 | free(ptrs_others.y); |
656 | return ret; | 746 | return ret; |
657 | } | 747 | } |
658 | 748 | ||
659 | static int crypto_bits(uint32_t *buf, int a2) | 749 | static int set_field_poly(uint32_t *field_poly, int field_sz) |
660 | { | 750 | { |
661 | clear_memory(buf, g_decode_A_info.nr_dwords); | 751 | clear_memory(field_poly, g_decode_A_info.nr_dwords); |
662 | g_decode_A_info.field_34 = 0; | 752 | g_decode_A_info.field_bits = 0; |
663 | if(a2 == 4) | 753 | if(field_sz == 4) |
664 | { | 754 | { |
665 | set_bit(0, buf); | 755 | set_bit(0, field_poly); |
666 | set_bit(74, buf); | 756 | set_bit(74, field_poly); |
667 | set_bit(233, buf); | 757 | set_bit(233, field_poly); |
668 | g_decode_A_info.field_34 = 233; | 758 | g_decode_A_info.field_bits = 233; |
669 | return 0; | 759 | return 0; |
670 | } | 760 | } |
671 | else if (a2 == 5) | 761 | else if (field_sz == 5) |
672 | { | 762 | { |
673 | set_bit(0, buf); | 763 | set_bit(0, field_poly); |
674 | set_bit(3, buf); | 764 | set_bit(3, field_poly); |
675 | set_bit(6, buf); | 765 | set_bit(6, field_poly); |
676 | set_bit(7, buf); | 766 | set_bit(7, field_poly); |
677 | set_bit(163, buf); | 767 | set_bit(163, field_poly); |
678 | g_decode_A_info.field_34 = 163; | 768 | g_decode_A_info.field_bits = 163; |
679 | return 0; | 769 | return 0; |
680 | } | 770 | } |
681 | else | 771 | else |
682 | return 1; | 772 | return 1; |
683 | } | 773 | } |
684 | 774 | ||
685 | static int crypto_bits_copy(ptr_bundle_t *a1, char a2) | 775 | static int ec_init(ec_point_t *a1, char field_sz) |
686 | { | 776 | { |
687 | int ret = crypto_bits(g_decode_A_info.ptr5, a2); | 777 | int ret = set_field_poly(g_decode_A_info.field_poly, field_sz); |
688 | if(ret) return ret; | 778 | if(ret) return ret; |
689 | if(a2 == 4) | 779 | if(field_sz == 4) |
690 | { | 780 | { |
691 | copy_memory(a1->ptrA, g_crypto_table); | 781 | copy_memory(a1->x, g_crypto_table); |
692 | copy_memory(a1->ptrB, g_crypto_table2); | 782 | copy_memory(a1->y, g_crypto_table2); |
693 | copy_memory(g_decode_A_info.ptr6, g_crypto_data); | 783 | copy_memory(g_decode_A_info.ec_a, g_atj_ec233_a); |
694 | copy_memory(g_decode_A_info.ptr7, g_crypto_key6); | 784 | copy_memory(g_decode_A_info.ptr7, g_crypto_key6); |
695 | return 0; | 785 | return 0; |
696 | } | 786 | } |
697 | else if ( a2 == 5 ) | 787 | else if(field_sz == 5 ) |
698 | { | 788 | { |
699 | copy_memory(a1->ptrA, g_crypto_key3); | 789 | copy_memory(a1->x, g_crypto_key3); |
700 | copy_memory(a1->ptrB, g_crypto_key4); | 790 | copy_memory(a1->y, g_crypto_key4); |
701 | copy_memory(g_decode_A_info.ptr6, g_crypto_data3); | 791 | copy_memory(g_decode_A_info.ec_a, g_atj_ec163_a); |
702 | copy_memory(g_decode_A_info.ptr7, g_crypto_key5); | 792 | copy_memory(g_decode_A_info.ptr7, g_crypto_key5); |
703 | return 0; | 793 | return 0; |
704 | } | 794 | } |
@@ -764,31 +854,30 @@ static int get_key_fwu_v3(size_t size, uint8_t *buf, uint8_t *blockA, uint8_t *b | |||
764 | 854 | ||
765 | cprintf(BLUE, "Main\n"); | 855 | cprintf(BLUE, "Main\n"); |
766 | 856 | ||
767 | // WARNING you need more that 48 because 17+32 > 48 !! (see code below) */ | 857 | struct fwu_crypto_hdr_t crypto_hdr; |
768 | uint8_t smallbuf[50]; | 858 | memcpy(&crypto_hdr, buf + sizeof(struct fwu_hdr_t), sizeof(crypto_hdr)); |
769 | memcpy(smallbuf, buf + 42, sizeof(smallbuf)); | 859 | cprintf_field(" Byte: ", "%d ", crypto_hdr.unk); |
770 | cprintf_field(" Byte: ", "%d ", smallbuf[16]); | 860 | check_field(crypto_hdr.unk, 3, "Ok\n", "Mismatch\n"); |
771 | check_field(smallbuf[16], 3, "Ok\n", "Mismatch\n"); | 861 | |
772 | 862 | ec_point_t ptrs; | |
773 | ptr_bundle_t ptrs; | 863 | ptrs.x = malloc(g_decode_A_info.size); |
774 | ptrs.ptrA = malloc(g_decode_A_info.size); | 864 | ptrs.y = malloc(g_decode_A_info.size); |
775 | ptrs.ptrB = malloc(g_decode_A_info.size); | 865 | memset(ptrs.x, 0, g_decode_A_info.size); |
776 | memset(ptrs.ptrA, 0, g_decode_A_info.size); | 866 | memset(ptrs.y, 0, g_decode_A_info.size); |
777 | memset(ptrs.ptrB, 0, g_decode_A_info.size); | 867 | memcpy(ptrs.x, buf + 91, g_decode_A_info.nr_bytes2); |
778 | memcpy(ptrs.ptrA, buf + 91, g_decode_A_info.nr_bytes2); | 868 | memcpy(ptrs.y, buf + 91 + g_decode_A_info.nr_bytes2, g_decode_A_info.nr_bytes2); |
779 | memcpy(ptrs.ptrB, buf + 91 + g_decode_A_info.nr_bytes2, g_decode_A_info.nr_bytes2); | 869 | |
780 | 870 | ret = ec_init(&g_decode_A_info.ptr1, g_crypto_info_byte); | |
781 | ret = crypto_bits_copy(&g_decode_A_info.ptr1, g_crypto_info_byte); | ||
782 | cprintf(GREEN, " Crypto bits copy: "); | 871 | cprintf(GREEN, " Crypto bits copy: "); |
783 | check_field(ret, 0, "Pass\n", "Fail\n"); | 872 | check_field(ret, 0, "Pass\n", "Fail\n"); |
784 | 873 | ||
785 | ret = crypto4(smallbuf + 17, &ptrs, g_decode_buffer3); | 874 | ret = crypto4(crypto_hdr.key, &ptrs, g_decode_buffer3); |
786 | cprintf(GREEN, " Crypto 4: "); | 875 | cprintf(GREEN, " Crypto 4: "); |
787 | check_field(ret, 0, "Pass\n", "Fail\n"); | 876 | check_field(ret, 0, "Pass\n", "Fail\n"); |
788 | 877 | ||
789 | memcpy(keybuf, &smallbuf[17], 32); | 878 | memcpy(keybuf, crypto_hdr.key, 32); |
790 | int offset = g_decode_A_info.nr_words + 91; | 879 | int offset = g_decode_A_info.nr_words + 91; |
791 | 880 | ||
792 | decode_block_with_swap(keybuf, 0, &buf[offset], 512 - offset, g_perm_B); | 881 | decode_block_with_swap(keybuf, 0, &buf[offset], 512 - offset, g_perm_B); |
793 | 882 | ||
794 | int pos = *(uint16_t *)&buf[offset]; | 883 | int pos = *(uint16_t *)&buf[offset]; |