summaryrefslogtreecommitdiff
path: root/utils/atj2137/atjboottool/fwu.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-10-26 18:16:00 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-10-26 18:17:59 +0100
commit7807934a271e9eb7b045cdcd89ba70fb59a91d69 (patch)
treeffe7ba88cd88aa7d32f3484edb11eec59204b333 /utils/atj2137/atjboottool/fwu.c
parent3ad9caeb2a8443b5975fb91c83d2793166a4e4f6 (diff)
downloadrockbox-7807934a271e9eb7b045cdcd89ba70fb59a91d69.tar.gz
rockbox-7807934a271e9eb7b045cdcd89ba70fb59a91d69.zip
atjboottool: document more header fields and crypto code
The encryption definitely uses some standard elliptic curve encryption over binary fields (163 and 233 bits, standard polynomials). It is still unclear how this is used in the actual encryption, the key authentification and derivation do not look standard. Change-Id: I6b9180ff7e6115e1dceca8489e986a02a9ea6fc9
Diffstat (limited to 'utils/atj2137/atjboottool/fwu.c')
-rw-r--r--utils/atj2137/atjboottool/fwu.c431
1 files changed, 260 insertions, 171 deletions
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
55struct fwu_crypto_hdr_t
56{
57 uint8_t field0[16];
58 uint8_t unk;
59 uint8_t key[32];
60} __attribute__((packed));
61
55struct fwu_tail_t 62struct 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
85typedef struct ptr_bundle_t 92typedef 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
91struct block_A_info_t 98struct 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;
125void *g_decode_buffer3; 132void *g_decode_buffer3;
126 133
127#include "atj_tables.h" 134#include "atj_tables.h"
135#include <ctype.h>
136
137void 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
129void compute_checksum(uint8_t *buf, size_t size, uint8_t t[20]) 158void 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
343static 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
367static void copy_memory(uint32_t *to, uint32_t *from) 373static 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
410static void decode_with_xor(uint32_t *res, uint32_t *key) 416static 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
436static 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
463static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) 489static 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
486static void xor_mult(uint32_t *a1, uint32_t *a2, uint32_t *a3) 512static 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
499static void xor_mult_high(uint32_t *a1, uint32_t *buf, uint32_t *a3) 525static 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
515static void xor_small(uint32_t *res, uint32_t *a, uint32_t *b) 540static 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
521static void crypto(ptr_bundle_t *a1, ptr_bundle_t *a2) 546static 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
553static uint32_t g_gf_one[9] =
554{
555 1, 0, 0, 0, 0, 0, 0, 0, 0
556};
557
558static 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
559static void crypto2(ptr_bundle_t *a1, ptr_bundle_t *a2, ptr_bundle_t *a3) 605static 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
595static int crypto3(uint32_t *a1, ptr_bundle_t *ptrs_alt, ptr_bundle_t *ptrs) 653static 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
643static int crypto4(uint8_t *a1, ptr_bundle_t *ptrs, uint32_t *a3) 709static 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
733static 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
659static int crypto_bits(uint32_t *buf, int a2) 749static 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
685static int crypto_bits_copy(ptr_bundle_t *a1, char a2) 775static 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];