diff options
author | Amaury Pouly <pamaury@rockbox.org> | 2011-04-17 23:28:18 +0000 |
---|---|---|
committer | Amaury Pouly <pamaury@rockbox.org> | 2011-04-17 23:28:18 +0000 |
commit | 84c70b2c5ba69fce3d62a2522e94a6ed537d0acf (patch) | |
tree | 24a3af99cad4569fc5af5e5c33992a0cdd9d4c65 /utils/sbtools | |
parent | b2c59541b47e98fe69ab973ca4ab2688d70aac23 (diff) |
elftosb: implement encryption support; now fully working
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29743 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils/sbtools')
-rw-r--r-- | utils/sbtools/elftosb.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c index 28717fddd9..de041f9207 100644 --- a/utils/sbtools/elftosb.c +++ b/utils/sbtools/elftosb.c @@ -843,6 +843,10 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) bugp("cannot open output file"); byte real_key[16]; + byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys); + /* init CBC-MACs */ + for(int i = 0; i < g_nr_keys; i++) + memset(cbc_macs[i], 0, 16); fill_gaps(sb); compute_sb_offsets(sb); @@ -857,6 +861,10 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) produce_sb_header(sb, &sb_hdr); sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr)); write(fd, &sb_hdr, sizeof(sb_hdr)); + /* update CBC-MACs */ + for(int i = 0; i < g_nr_keys; i++) + cbc_mac((byte *)&sb_hdr, NULL, sizeof(sb_hdr) / BLOCK_SIZE, g_key_array[i], + cbc_macs[i], &cbc_macs[i], 1); /* produce and write section headers */ for(int i = 0; i < sb_hdr.nr_sections; i++) @@ -865,32 +873,60 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) produce_sb_section_header(&sb->sections[i], &sb_sec_hdr); sha_1_update(&file_sha1, (byte *)&sb_sec_hdr, sizeof(sb_sec_hdr)); write(fd, &sb_sec_hdr, sizeof(sb_sec_hdr)); + /* update CBC-MACs */ + for(int j = 0; j < g_nr_keys; j++) + cbc_mac((byte *)&sb_sec_hdr, NULL, sizeof(sb_sec_hdr) / BLOCK_SIZE, + g_key_array[j], cbc_macs[j], &cbc_macs[j], 1); } /* produce key dictionary */ + for(int i = 0; i < g_nr_keys; i++) + { + struct sb_key_dictionary_entry_t entry; + memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16); + cbc_mac(real_key, entry.key, sizeof(real_key) / BLOCK_SIZE, g_key_array[i], + (byte *)&sb_hdr, NULL, 1); + + write(fd, &entry, sizeof(entry)); + sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry)); + } /* produce sections data */ for(int i = 0; i< sb_hdr.nr_sections; i++) { /* produce tag command */ struct sb_instruction_tag_t tag_cmd; produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections); + if(g_nr_keys > 0) + cbc_mac((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE, + real_key, (byte *)&sb_hdr, NULL, 1); sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd)); write(fd, &tag_cmd, sizeof(tag_cmd)); /* produce other commands */ + byte cur_cbc_mac[16]; + memcpy(cur_cbc_mac, (byte *)&sb_hdr, 16); for(int j = 0; j < sb->sections[i].nr_insts; j++) { struct sb_inst_t *inst = &sb->sections[i].insts[j]; /* command */ struct sb_instruction_common_t cmd; produce_sb_instruction(inst, &cmd); + if(g_nr_keys > 0) + cbc_mac((byte *)&cmd, (byte *)&cmd, sizeof(cmd) / BLOCK_SIZE, + real_key, cur_cbc_mac, &cur_cbc_mac, 1); sha_1_update(&file_sha1, (byte *)&cmd, sizeof(cmd)); write(fd, &cmd, sizeof(cmd)); /* data */ if(inst->inst == SB_INST_LOAD) { - sha_1_update(&file_sha1, inst->data, inst->size); - write(fd, inst->data, inst->size); - sha_1_update(&file_sha1, inst->padding, inst->padding_size); - write(fd, inst->padding, inst->padding_size); + uint32_t sz = inst->size + inst->padding_size; + byte *data = xmalloc(sz); + memcpy(data, inst->data, inst->size); + memcpy(data + inst->size, inst->padding, inst->padding_size); + if(g_nr_keys > 0) + cbc_mac(data, data, sz / BLOCK_SIZE, + real_key, cur_cbc_mac, &cur_cbc_mac, 1); + sha_1_update(&file_sha1, data, sz); + write(fd, data, sz); + free(data); } } } @@ -899,6 +935,8 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename) sha_1_finish(&file_sha1); sha_1_output(&file_sha1, final_sig); generate_random_data(final_sig + 20, 12); + if(g_nr_keys > 0) + cbc_mac(final_sig, final_sig, 2, real_key, (byte *)&sb_hdr, NULL, 1); write(fd, final_sig, 32); close(fd); |