diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-01 20:48:05 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-16 19:58:24 +0100 |
commit | 2b20026dd755706934f8f8e1a192bffdfc3d717c (patch) | |
tree | 3c8bb119ab5e9d3f62093563e99609c7dc2a8f2f /utils/imxtools/sbtools/sb.c | |
parent | cb8a98e365c0b69e068dc077eb5d68dd4a29a1ad (diff) | |
download | rockbox-2b20026dd755706934f8f8e1a192bffdfc3d717c.tar.gz rockbox-2b20026dd755706934f8f8e1a192bffdfc3d717c.zip |
imxtools/sbtools: rework cryptography
It was a mess, a mix of crypto_* and cbc_mac calls. I made everything call crypto
functions, and also separate key setup from cryptographic operations, this will
be useful to speed up the code in the upcoming commits. Drop support for "usbotp"
key, since the crypto code for that was never mainlined and we can always get the
keys from a device as long as we have code execution (using the DCP debug registers).
Change-Id: I7aa24d12207ffb744225d1b9cc7cb1dc7281dd22
Diffstat (limited to 'utils/imxtools/sbtools/sb.c')
-rw-r--r-- | utils/imxtools/sbtools/sb.c | 148 |
1 files changed, 84 insertions, 64 deletions
diff --git a/utils/imxtools/sbtools/sb.c b/utils/imxtools/sbtools/sb.c index 145df39762..ff8e0da3ee 100644 --- a/utils/imxtools/sbtools/sb.c +++ b/utils/imxtools/sbtools/sb.c | |||
@@ -322,6 +322,12 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
322 | byte *buf = xmalloc(sb_hdr.image_size * BLOCK_SIZE); | 322 | byte *buf = xmalloc(sb_hdr.image_size * BLOCK_SIZE); |
323 | byte *buf_p = buf; | 323 | byte *buf_p = buf; |
324 | #define write(p, sz) do { memcpy(buf_p, p, sz); buf_p += sz; } while(0) | 324 | #define write(p, sz) do { memcpy(buf_p, p, sz); buf_p += sz; } while(0) |
325 | #define check_crypto(expr) \ | ||
326 | do { int err = expr; \ | ||
327 | if(err != CRYPTO_ERROR_SUCCESS) { \ | ||
328 | free(cbc_macs); \ | ||
329 | cprintf(u, true, GREY, "Crypto error: %d\n", err); \ | ||
330 | return SB_CRYPTO_ERROR; } } while(0) | ||
325 | 331 | ||
326 | sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); | 332 | sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); |
327 | write(&sb_hdr, sizeof(sb_hdr)); | 333 | write(&sb_hdr, sizeof(sb_hdr)); |
@@ -330,8 +336,11 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
330 | 336 | ||
331 | /* update CBC-MACs */ | 337 | /* update CBC-MACs */ |
332 | for(int i = 0; i < g_nr_keys; i++) | 338 | for(int i = 0; i < g_nr_keys; i++) |
333 | crypto_cbc((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, &g_key_array[i], | 339 | { |
334 | cbc_macs[i], &cbc_macs[i], 1); | 340 | check_crypto(crypto_setup(&g_key_array[i])); |
341 | check_crypto(crypto_apply((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, | ||
342 | cbc_macs[i], &cbc_macs[i], true)); | ||
343 | } | ||
335 | 344 | ||
336 | /* produce and write section headers */ | 345 | /* produce and write section headers */ |
337 | for(int i = 0; i < sb_hdr.nr_sections; i++) | 346 | for(int i = 0; i < sb_hdr.nr_sections; i++) |
@@ -342,23 +351,23 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
342 | write(&sb_sec_hdr, sizeof(sb_sec_hdr)); | 351 | write(&sb_sec_hdr, sizeof(sb_sec_hdr)); |
343 | /* update CBC-MACs */ | 352 | /* update CBC-MACs */ |
344 | for(int j = 0; j < g_nr_keys; j++) | 353 | for(int j = 0; j < g_nr_keys; j++) |
345 | crypto_cbc((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE, | 354 | { |
346 | &g_key_array[j], cbc_macs[j], &cbc_macs[j], 1); | 355 | check_crypto(crypto_setup(&g_key_array[j])); |
356 | check_crypto(crypto_apply((byte *)&sb_sec_hdr, NULL, | ||
357 | sizeof(sb_sec_hdr) / BLOCK_SIZE, cbc_macs[j], &cbc_macs[j], true)); | ||
358 | } | ||
347 | } | 359 | } |
348 | /* produce key dictionary */ | 360 | /* produce key dictionary */ |
349 | for(int i = 0; i < g_nr_keys; i++) | 361 | for(int i = 0; i < g_nr_keys; i++) |
350 | { | 362 | { |
351 | struct sb_key_dictionary_entry_t entry; | 363 | struct sb_key_dictionary_entry_t entry; |
352 | memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); | 364 | memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); |
353 | crypto_cbc(real_key.u.key, entry.key, 1, &g_key_array[i], | 365 | check_crypto(crypto_setup(&g_key_array[i])); |
354 | crypto_iv, NULL, 1); | 366 | check_crypto(crypto_apply(real_key.u.key, entry.key, 1, crypto_iv, NULL, true)); |
355 | |||
356 | write(&entry, sizeof(entry)); | 367 | write(&entry, sizeof(entry)); |
357 | sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); | 368 | sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); |
358 | } | 369 | } |
359 | 370 | ||
360 | free(cbc_macs); | ||
361 | |||
362 | /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */ | 371 | /* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */ |
363 | /* Image crafting, don't use it unless you understand what you do */ | 372 | /* Image crafting, don't use it unless you understand what you do */ |
364 | if(sb->override_real_key) | 373 | if(sb->override_real_key) |
@@ -388,6 +397,8 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
388 | write(data, init_gap); | 397 | write(data, init_gap); |
389 | free(data); | 398 | free(data); |
390 | } | 399 | } |
400 | /* setup real key */ | ||
401 | check_crypto(crypto_setup(&real_key)); | ||
391 | /* produce sections data */ | 402 | /* produce sections data */ |
392 | for(int i = 0; i< sb_hdr.nr_sections; i++) | 403 | for(int i = 0; i< sb_hdr.nr_sections; i++) |
393 | { | 404 | { |
@@ -395,8 +406,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
395 | struct sb_instruction_tag_t tag_cmd; | 406 | struct sb_instruction_tag_t tag_cmd; |
396 | produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); | 407 | produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); |
397 | if(g_nr_keys > 0) | 408 | if(g_nr_keys > 0) |
398 | crypto_cbc((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, | 409 | { |
399 | &real_key, crypto_iv, NULL, 1); | 410 | check_crypto(crypto_apply((byte *)&tag_cmd, (byte *)&tag_cmd, |
411 | sizeof(tag_cmd) / BLOCK_SIZE, crypto_iv, NULL, true)); | ||
412 | } | ||
400 | sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); | 413 | sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); |
401 | write(&tag_cmd, sizeof(tag_cmd)); | 414 | write(&tag_cmd, sizeof(tag_cmd)); |
402 | /* produce other commands */ | 415 | /* produce other commands */ |
@@ -411,8 +424,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
411 | struct sb_instruction_common_t cmd; | 424 | struct sb_instruction_common_t cmd; |
412 | produce_sb_instruction(inst, &cmd, u, cprintf); | 425 | produce_sb_instruction(inst, &cmd, u, cprintf); |
413 | if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) | 426 | if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) |
414 | crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, | 427 | { |
415 | &real_key, cur_cbc_mac, &cur_cbc_mac, 1); | 428 | check_crypto(crypto_apply((byte *)&cmd, (byte *)&cmd, |
429 | sizeof(cmd) / BLOCK_SIZE, cur_cbc_mac, &cur_cbc_mac, true)); | ||
430 | } | ||
416 | sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); | 431 | sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); |
417 | write(&cmd, sizeof(cmd)); | 432 | write(&cmd, sizeof(cmd)); |
418 | } | 433 | } |
@@ -424,8 +439,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
424 | memcpy(data, inst->data, inst->size); | 439 | memcpy(data, inst->data, inst->size); |
425 | memcpy(data + inst->size, inst->padding, inst->padding_size); | 440 | memcpy(data + inst->size, inst->padding, inst->padding_size); |
426 | if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) | 441 | if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) |
427 | crypto_cbc(data, data, sz / BLOCK_SIZE, | 442 | { |
428 | &real_key, cur_cbc_mac, &cur_cbc_mac, 1); | 443 | check_crypto(crypto_apply(data, data, sz / BLOCK_SIZE, |
444 | cur_cbc_mac, &cur_cbc_mac, true)); | ||
445 | } | ||
429 | sha_1_update(&file_sha1, data, sz); | 446 | sha_1_update(&file_sha1, data, sz); |
430 | write(data, sz); | 447 | write(data, sz); |
431 | free(data); | 448 | free(data); |
@@ -450,8 +467,10 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
450 | cmd.hdr.opcode = SB_INST_NOP; | 467 | cmd.hdr.opcode = SB_INST_NOP; |
451 | cmd.hdr.checksum = instruction_checksum(&cmd.hdr); | 468 | cmd.hdr.checksum = instruction_checksum(&cmd.hdr); |
452 | if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) | 469 | if(g_nr_keys > 0 && !sb->sections[i].is_cleartext) |
453 | crypto_cbc((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, | 470 | { |
454 | &real_key, cur_cbc_mac, &cur_cbc_mac, 1); | 471 | check_crypto(crypto_apply((byte *)&cmd, (byte *)&cmd, |
472 | sizeof(cmd) / BLOCK_SIZE, cur_cbc_mac, &cur_cbc_mac, true)); | ||
473 | } | ||
455 | sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); | 474 | sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); |
456 | write(&cmd, sizeof(cmd)); | 475 | write(&cmd, sizeof(cmd)); |
457 | } | 476 | } |
@@ -463,28 +482,34 @@ enum sb_error_t sb_write_file(struct sb_file_t *sb, const char *filename, void * | |||
463 | sha_1_output(&file_sha1, final_sig); | 482 | sha_1_output(&file_sha1, final_sig); |
464 | generate_random_data(final_sig + 20, 12); | 483 | generate_random_data(final_sig + 20, 12); |
465 | if(g_nr_keys > 0) | 484 | if(g_nr_keys > 0) |
466 | crypto_cbc(final_sig, final_sig, 2, &real_key, crypto_iv, NULL, 1); | 485 | check_crypto(crypto_apply(final_sig, final_sig, 2, crypto_iv, NULL, true)); |
467 | write(final_sig, 32); | 486 | write(final_sig, 32); |
487 | |||
488 | free(cbc_macs); | ||
489 | |||
468 | if(buf_p - buf != sb_hdr.image_size * BLOCK_SIZE) | 490 | if(buf_p - buf != sb_hdr.image_size * BLOCK_SIZE) |
469 | { | 491 | { |
470 | printf(GREY, "[ERROR][INTERNAL] SB image buffer was not entirely filled !\n"); | 492 | free(buf); |
471 | printf(GREY, "[ERROR][INTERNAL] expected %u blocks, got %u\n", | 493 | printf(GREY, "Internal error: SB image buffer was not entirely filled !\n"); |
494 | printf(GREY, "Internal error: expected %u blocks, got %u\n", | ||
472 | (buf_p - buf) / BLOCK_SIZE, sb_hdr.image_size); | 495 | (buf_p - buf) / BLOCK_SIZE, sb_hdr.image_size); |
496 | cprintf(u, true, GREY, "Internal error\n"); | ||
473 | return SB_ERROR; | 497 | return SB_ERROR; |
474 | } | 498 | } |
475 | 499 | ||
476 | FILE *fd = fopen(filename, "wb"); | 500 | FILE *fd = fopen(filename, "wb"); |
477 | if(fd == NULL) | 501 | if(fd == NULL) |
478 | return SB_OPEN_ERROR; | 502 | return SB_OPEN_ERROR; |
479 | if(fwrite(buf, sb_hdr.image_size * BLOCK_SIZE, 1, fd) != 1) | 503 | int cnt = fwrite(buf, sb_hdr.image_size * BLOCK_SIZE, 1, fd); |
480 | { | 504 | if(cnt != 1) |
481 | free(buf); | 505 | printf(GREY, "Write error: %m\n"); |
482 | return SB_WRITE_ERROR; | ||
483 | } | ||
484 | fclose(fd); | ||
485 | free(buf); | 506 | free(buf); |
507 | fclose(fd); | ||
508 | if(cnt != 1) | ||
509 | return SB_WRITE_ERROR; | ||
486 | 510 | ||
487 | return SB_SUCCESS; | 511 | return SB_SUCCESS; |
512 | #undef check_crypto | ||
488 | #undef printf | 513 | #undef printf |
489 | } | 514 | } |
490 | 515 | ||
@@ -712,22 +737,28 @@ static void sb_printer(void *user, const char *fmt, ...) | |||
712 | } | 737 | } |
713 | 738 | ||
714 | struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, void *u, | 739 | struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, void *u, |
715 | generic_printf_t cprintf, enum sb_error_t *err) | 740 | generic_printf_t cprintf, enum sb_error_t *out_err) |
716 | { | 741 | { |
717 | struct sb_file_t *sb_file = NULL; | 742 | struct sb_file_t *sb_file = NULL; |
718 | uint8_t *buf = _buf; | 743 | uint8_t *buf = _buf; |
719 | 744 | ||
720 | #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) | 745 | #define printf(c, ...) cprintf(u, false, c, __VA_ARGS__) |
721 | #define fatal(e, ...) \ | 746 | #define fatal(e, ...) \ |
722 | do { if(err) *err = e; \ | 747 | do { if(out_err) *out_err = e; \ |
723 | cprintf(u, true, GREY, __VA_ARGS__); \ | 748 | cprintf(u, true, GREY, __VA_ARGS__); \ |
749 | free(cbcmacs); \ | ||
724 | sb_free(sb_file); \ | 750 | sb_free(sb_file); \ |
725 | return NULL; } while(0) | 751 | return NULL; } while(0) |
726 | struct printer_t printer = {.user = u, .cprintf = cprintf, .color = OFF, .error = false }; | 752 | struct printer_t printer = {.user = u, .cprintf = cprintf, .color = OFF, .error = false }; |
727 | #define print_hex(c, p, len, nl) \ | 753 | #define print_hex(c, p, len, nl) \ |
728 | do { printer.color = c; print_hex(&printer, sb_printer, p, len, nl); } while(0) | 754 | do { printer.color = c; print_hex(&printer, sb_printer, p, len, nl); } while(0) |
755 | #define check_crypto(expr) \ | ||
756 | do { int err = expr; \ | ||
757 | if(err != CRYPTO_ERROR_SUCCESS) \ | ||
758 | fatal(SB_CRYPTO_ERROR, "Crypto error: %d\n", err); } while(0) | ||
729 | 759 | ||
730 | struct sha_1_params_t sha_1_params; | 760 | struct sha_1_params_t sha_1_params; |
761 | byte (*cbcmacs)[16] = xmalloc(16 * g_nr_keys); | ||
731 | sb_file = xmalloc(sizeof(struct sb_file_t)); | 762 | sb_file = xmalloc(sizeof(struct sb_file_t)); |
732 | memset(sb_file, 0, sizeof(struct sb_file_t)); | 763 | memset(sb_file, 0, sizeof(struct sb_file_t)); |
733 | struct sb_header_t *sb_header = (struct sb_header_t *)buf; | 764 | struct sb_header_t *sb_header = (struct sb_header_t *)buf; |
@@ -826,12 +857,12 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
826 | printf(YELLOW, "0x%08x\n", sb_header->first_boot_sec_id); | 857 | printf(YELLOW, "0x%08x\n", sb_header->first_boot_sec_id); |
827 | 858 | ||
828 | /* encryption cbc-mac */ | 859 | /* encryption cbc-mac */ |
829 | byte real_key[16]; | 860 | struct crypto_key_t real_key; |
861 | real_key.method = CRYPTO_KEY; | ||
830 | bool valid_key = false; /* false until a matching key was found */ | 862 | bool valid_key = false; /* false until a matching key was found */ |
831 | 863 | ||
832 | if(sb_header->nr_keys > 0) | 864 | if(sb_header->nr_keys > 0) |
833 | { | 865 | { |
834 | byte (*cbcmacs)[16] = xmalloc(16 * g_nr_keys); | ||
835 | printf(BLUE, "Encryption keys\n"); | 866 | printf(BLUE, "Encryption keys\n"); |
836 | for(int i = 0; i < g_nr_keys; i++) | 867 | for(int i = 0; i < g_nr_keys; i++) |
837 | { | 868 | { |
@@ -843,13 +874,9 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
843 | /* check it */ | 874 | /* check it */ |
844 | byte zero[16]; | 875 | byte zero[16]; |
845 | memset(zero, 0, 16); | 876 | memset(zero, 0, 16); |
846 | int ret = crypto_cbc(buf, NULL, sb_header->header_size + sb_header->nr_sections, | 877 | check_crypto(crypto_setup(&g_key_array[i])); |
847 | &g_key_array[i], zero, &cbcmacs[i], 1); | 878 | check_crypto(crypto_apply(buf, NULL, sb_header->header_size + |
848 | if(ret != CRYPTO_ERROR_SUCCESS) | 879 | sb_header->nr_sections, zero, &cbcmacs[i], true)); |
849 | { | ||
850 | free(cbcmacs); | ||
851 | fatal(SB_FIRST_CRYPTO_ERROR + ret, "Crypto error: %d", ret); | ||
852 | } | ||
853 | print_hex(YELLOW, cbcmacs[i], 16, true); | 880 | print_hex(YELLOW, cbcmacs[i], 16, true); |
854 | } | 881 | } |
855 | 882 | ||
@@ -878,24 +905,20 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
878 | byte decrypted_key[16]; | 905 | byte decrypted_key[16]; |
879 | byte iv[16]; | 906 | byte iv[16]; |
880 | memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ | 907 | memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */ |
881 | int ret = crypto_cbc(dict_entry->key, decrypted_key, 1, &g_key_array[idx], iv, NULL, 0); | 908 | check_crypto(crypto_setup(&g_key_array[idx])); |
882 | if(ret != CRYPTO_ERROR_SUCCESS) | 909 | check_crypto(crypto_apply(dict_entry->key, decrypted_key, 1, iv, NULL, false)); |
883 | { | ||
884 | free(cbcmacs); | ||
885 | fatal(SB_FIRST_CRYPTO_ERROR + ret, "Crypto error: %d\n", ret); | ||
886 | } | ||
887 | printf(GREEN, " Decrypted key: "); | 910 | printf(GREEN, " Decrypted key: "); |
888 | print_hex(YELLOW, decrypted_key, 16, false); | 911 | print_hex(YELLOW, decrypted_key, 16, false); |
889 | if(valid_key) | 912 | if(valid_key) |
890 | { | 913 | { |
891 | if(memcmp(real_key, decrypted_key, 16) == 0) | 914 | if(memcmp(real_key.u.key, decrypted_key, 16) == 0) |
892 | printf(RED, " Cross-Check Ok"); | 915 | printf(RED, " Cross-Check Ok"); |
893 | else | 916 | else |
894 | printf(RED, " Cross-Check Failed"); | 917 | printf(RED, " Cross-Check Failed"); |
895 | } | 918 | } |
896 | else | 919 | else |
897 | { | 920 | { |
898 | memcpy(real_key, decrypted_key, 16); | 921 | memcpy(real_key.u.key, decrypted_key, 16); |
899 | valid_key = true; | 922 | valid_key = true; |
900 | } | 923 | } |
901 | printf(OFF, "\n"); | 924 | printf(OFF, "\n"); |
@@ -904,8 +927,6 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
904 | printf(RED, " Don't Match\n"); | 927 | printf(RED, " Don't Match\n"); |
905 | } | 928 | } |
906 | 929 | ||
907 | free(cbcmacs); | ||
908 | |||
909 | if(!valid_key) | 930 | if(!valid_key) |
910 | { | 931 | { |
911 | if(g_force) | 932 | if(g_force) |
@@ -916,11 +937,9 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
916 | 937 | ||
917 | if(getenv("SB_REAL_KEY") != 0) | 938 | if(getenv("SB_REAL_KEY") != 0) |
918 | { | 939 | { |
919 | struct crypto_key_t k; | ||
920 | char *env = getenv("SB_REAL_KEY"); | 940 | char *env = getenv("SB_REAL_KEY"); |
921 | if(!parse_key(&env, &k) || *env) | 941 | if(!parse_key(&env, &real_key) || *env) |
922 | fatal(SB_ERROR, "Invalid SB_REAL_KEY\n"); | 942 | fatal(SB_ERROR, "Invalid SB_REAL_KEY\n"); |
923 | memcpy(real_key, k.u.key, 16); | ||
924 | /* assume the key is valid */ | 943 | /* assume the key is valid */ |
925 | if(valid_key) | 944 | if(valid_key) |
926 | printf(GREY, " Overriding real key\n"); | 945 | printf(GREY, " Overriding real key\n"); |
@@ -931,16 +950,17 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
931 | 950 | ||
932 | printf(RED, " Summary:\n"); | 951 | printf(RED, " Summary:\n"); |
933 | printf(GREEN, " Real key: "); | 952 | printf(GREEN, " Real key: "); |
934 | print_hex(YELLOW, real_key, 16, true); | 953 | print_hex(YELLOW, real_key.u.key, 16, true); |
935 | printf(GREEN, " IV : "); | 954 | printf(GREEN, " IV : "); |
936 | print_hex(YELLOW, buf, 16, true); | 955 | print_hex(YELLOW, buf, 16, true); |
937 | 956 | ||
938 | memcpy(sb_file->real_key, real_key, 16); | 957 | memcpy(sb_file->real_key, real_key.u.key, 16); |
939 | memcpy(sb_file->crypto_iv, buf, 16); | 958 | memcpy(sb_file->crypto_iv, buf, 16); |
959 | /* setup real key if needed */ | ||
960 | check_crypto(crypto_setup(&real_key)); | ||
940 | } | 961 | } |
941 | else | 962 | else |
942 | valid_key = true; | 963 | valid_key = true; |
943 | |||
944 | /* sections */ | 964 | /* sections */ |
945 | if(!(flags & SB_RAW_MODE)) | 965 | if(!(flags & SB_RAW_MODE)) |
946 | { | 966 | { |
@@ -986,12 +1006,13 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
986 | /* save it */ | 1006 | /* save it */ |
987 | byte *sec = xmalloc(size); | 1007 | byte *sec = xmalloc(size); |
988 | if(encrypted) | 1008 | if(encrypted) |
989 | cbc_mac(buf + pos, sec, size / BLOCK_SIZE, real_key, buf, NULL, 0); | 1009 | check_crypto(crypto_apply(buf + pos, sec, size / BLOCK_SIZE, buf, NULL, false)); |
990 | else | 1010 | else |
991 | memcpy(sec, buf + pos, size); | 1011 | memcpy(sec, buf + pos, size); |
992 | 1012 | ||
993 | struct sb_section_t *s = read_section(data_sec, sec_hdr->identifier, | 1013 | struct sb_section_t *s = read_section(data_sec, sec_hdr->identifier, |
994 | sec, size, " ", u, cprintf, err); | 1014 | sec, size, " ", u, cprintf, out_err); |
1015 | free(sec); | ||
995 | if(s) | 1016 | if(s) |
996 | { | 1017 | { |
997 | s->other_flags = sec_hdr->flags & ~SECTION_STD_MASK; | 1018 | s->other_flags = sec_hdr->flags & ~SECTION_STD_MASK; |
@@ -1001,9 +1022,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
1001 | free(s); | 1022 | free(s); |
1002 | } | 1023 | } |
1003 | else | 1024 | else |
1004 | fatal(*err, "Error reading section\n"); | 1025 | fatal(*out_err, "Error reading section\n"); |
1005 | |||
1006 | free(sec); | ||
1007 | } | 1026 | } |
1008 | } | 1027 | } |
1009 | else if(valid_key) | 1028 | else if(valid_key) |
@@ -1019,7 +1038,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
1019 | memcpy(iv, buf, 16); | 1038 | memcpy(iv, buf, 16); |
1020 | byte cmd[BLOCK_SIZE]; | 1039 | byte cmd[BLOCK_SIZE]; |
1021 | if(sb_header->nr_keys > 0) | 1040 | if(sb_header->nr_keys > 0) |
1022 | cbc_mac(buf + offset, cmd, 1, real_key, iv, &iv, 0); | 1041 | check_crypto(crypto_apply(buf + offset, cmd, 1, iv, &iv, false)); |
1023 | else | 1042 | else |
1024 | memcpy(cmd, buf + offset, BLOCK_SIZE); | 1043 | memcpy(cmd, buf + offset, BLOCK_SIZE); |
1025 | struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)cmd; | 1044 | struct sb_instruction_header_t *hdr = (struct sb_instruction_header_t *)cmd; |
@@ -1077,12 +1096,13 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
1077 | /* save it */ | 1096 | /* save it */ |
1078 | byte *sec = xmalloc(size); | 1097 | byte *sec = xmalloc(size); |
1079 | if(encrypted) | 1098 | if(encrypted) |
1080 | cbc_mac(buf + pos, sec, size / BLOCK_SIZE, real_key, buf, NULL, 0); | 1099 | check_crypto(crypto_apply(buf + pos, sec, size / BLOCK_SIZE, buf, NULL, false)); |
1081 | else | 1100 | else |
1082 | memcpy(sec, buf + pos, size); | 1101 | memcpy(sec, buf + pos, size); |
1083 | 1102 | ||
1084 | struct sb_section_t *s = read_section(data_sec, tag->identifier, | 1103 | struct sb_section_t *s = read_section(data_sec, tag->identifier, |
1085 | sec, size, " ", u, cprintf, err); | 1104 | sec, size, " ", u, cprintf, out_err); |
1105 | free(sec); | ||
1086 | if(s) | 1106 | if(s) |
1087 | { | 1107 | { |
1088 | s->other_flags = tag->flags & ~SECTION_STD_MASK; | 1108 | s->other_flags = tag->flags & ~SECTION_STD_MASK; |
@@ -1094,8 +1114,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
1094 | free(s); | 1114 | free(s); |
1095 | } | 1115 | } |
1096 | else | 1116 | else |
1097 | fatal(*err, "Error reading section\n"); | 1117 | fatal(*out_err, "Error reading section\n"); |
1098 | free(sec); | ||
1099 | 1118 | ||
1100 | /* last one ? */ | 1119 | /* last one ? */ |
1101 | if(tag->hdr.flags & SB_INST_LAST_TAG) | 1120 | if(tag->hdr.flags & SB_INST_LAST_TAG) |
@@ -1126,7 +1145,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
1126 | printf(OFF, " "); | 1145 | printf(OFF, " "); |
1127 | print_hex(YELLOW, encrypted_block + 16, 16, true); | 1146 | print_hex(YELLOW, encrypted_block + 16, 16, true); |
1128 | /* decrypt it */ | 1147 | /* decrypt it */ |
1129 | cbc_mac(encrypted_block, decrypted_block, 2, real_key, buf, NULL, 0); | 1148 | check_crypto(crypto_apply(encrypted_block, decrypted_block, 2, buf, NULL, false)); |
1130 | } | 1149 | } |
1131 | else | 1150 | else |
1132 | memcpy(decrypted_block, &buf[filesize - 32], 32); | 1151 | memcpy(decrypted_block, &buf[filesize - 32], 32); |
@@ -1153,6 +1172,7 @@ struct sb_file_t *sb_read_memory(void *_buf, size_t filesize, unsigned flags, vo | |||
1153 | fatal(SB_CHECKSUM_ERROR, "File SHA-1 error\n"); | 1172 | fatal(SB_CHECKSUM_ERROR, "File SHA-1 error\n"); |
1154 | } | 1173 | } |
1155 | 1174 | ||
1175 | free(cbcmacs); | ||
1156 | return sb_file; | 1176 | return sb_file; |
1157 | #undef printf | 1177 | #undef printf |
1158 | #undef fatal | 1178 | #undef fatal |