sbtools: be more verbose on real key and iv; add very advanced code to craft images

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30835 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Amaury Pouly 2011-10-23 22:31:48 +00:00
parent f45fb77664
commit 4ef4830f0b
2 changed files with 65 additions and 9 deletions

View file

@ -773,6 +773,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
bugp("cannot open output file");
byte real_key[16];
byte crypto_iv[16];
byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys);
/* init CBC-MACs */
for(int i = 0; i < g_nr_keys; i++)
@ -791,6 +792,9 @@ 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));
memcpy(crypto_iv, &sb_hdr, 16);
/* 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],
@ -814,11 +818,53 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
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);
crypto_iv, NULL, 1);
write(fd, &entry, sizeof(entry));
sha_1_update(&file_sha1, (byte *)&entry, sizeof(entry));
}
/* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK */
/* Image crafting, don't use it unless you understand what you do */
if(strlen(s_getenv("SB_OVERRIDE_REAL_KEY")) != 0)
{
const char *key = s_getenv("SB_OVERRIDE_REAL_KEY");
if(strlen(key) != 32)
bugp("Cannot override real key: invalid key length\n");
for(int i = 0; i < 16; i++)
{
byte a, b;
if(convxdigit(key[2 * i], &a) || convxdigit(key[2 * i + 1], &b))
bugp("Cannot override real key: key should be a 128-bit key written in hexadecimal\n");
real_key[i] = (a << 4) | b;
}
}
if(strlen(s_getenv("SB_OVERRIDE_IV")) != 0)
{
const char *iv = s_getenv("SB_OVERRIDE_IV");
if(strlen(iv) != 32)
bugp("Cannot override iv: invalid key length\n");
for(int i = 0; i < 16; i++)
{
byte a, b;
if(convxdigit(iv[2 * i], &a) || convxdigit(iv[2 * i + 1], &b))
bugp("Cannot override iv: key should be a 128-bit key written in hexadecimal\n");
crypto_iv[i] = (a << 4) | b;
}
}
/* KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH KCAH */
if(g_debug)
{
printf("Real key: ");
for(int j = 0; j < 16; j++)
printf("%02x", real_key[j]);
printf("\n");
printf("IV : ");
for(int j = 0; j < 16; j++)
printf("%02x", crypto_iv[j]);
printf("\n");
}
/* produce sections data */
for(int i = 0; i< sb_hdr.nr_sections; i++)
{
@ -827,12 +873,12 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
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);
real_key, crypto_iv, 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);
memcpy(cur_cbc_mac, crypto_iv, 16);
for(int j = 0; j < sb->sections[i].nr_insts; j++)
{
struct sb_inst_t *inst = &sb->sections[i].insts[j];
@ -869,7 +915,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
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);
cbc_mac(final_sig, final_sig, 2, real_key, crypto_iv, NULL, 1);
write(fd, final_sig, 32);
close(fd);

View file

@ -372,8 +372,10 @@ static void extract(unsigned long filesize)
if(memcmp(sb_header->signature, "STMP", 4) != 0)
bugp("Bad signature");
/*
if(sb_header->image_size * BLOCK_SIZE > filesize)
bugp("File size mismatch");
*/
if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t))
bugp("Bad header size");
if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t))
@ -555,6 +557,17 @@ static void extract(unsigned long filesize)
}
}
color(RED);
printf(" Summary:\n");
color(GREEN);
printf(" Real key: ");
color(YELLOW);
print_hex(real_key, 16, true);
color(GREEN);
printf(" IV : ");
color(YELLOW);
print_hex(g_buf, 16, true);
/* sections */
if(strcasecmp(s_getenv("SB_RAW_CMD"), "YES") != 0)
{
@ -615,10 +628,11 @@ static void extract(unsigned long filesize)
printf("Commands\n");
uint32_t offset = sb_header->first_boot_tag_off * BLOCK_SIZE;
byte iv[16];
memcpy(iv, g_buf, 16);
const char *indent = " ";
while(true)
{
/* restart with IV */
memcpy(iv, g_buf, 16);
byte cmd[BLOCK_SIZE];
if(sb_header->nr_keys > 0)
cbc_mac(g_buf + offset, cmd, 1, real_key, iv, &iv, 0);
@ -638,8 +652,6 @@ static void extract(unsigned long filesize)
color(RED);
printf("NOOP\n");
offset += BLOCK_SIZE;
/* restart with IV */
memcpy(iv, g_buf, 16);
}
else if(hdr->opcode == SB_INST_TAG)
{
@ -712,8 +724,6 @@ static void extract(unsigned long filesize)
if(tag->hdr.flags & SB_INST_LAST_TAG)
break;
offset += size;
/* restart with IV */
memcpy(iv, g_buf, 16);
}
else
{