forked from len0rd/rockbox
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:
parent
f45fb77664
commit
4ef4830f0b
2 changed files with 65 additions and 9 deletions
|
|
@ -773,6 +773,7 @@ static void produce_sb_file(struct sb_file_t *sb, const char *filename)
|
||||||
bugp("cannot open output file");
|
bugp("cannot open output file");
|
||||||
|
|
||||||
byte real_key[16];
|
byte real_key[16];
|
||||||
|
byte crypto_iv[16];
|
||||||
byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys);
|
byte (*cbc_macs)[16] = xmalloc(16 * g_nr_keys);
|
||||||
/* init CBC-MACs */
|
/* init CBC-MACs */
|
||||||
for(int i = 0; i < g_nr_keys; i++)
|
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);
|
produce_sb_header(sb, &sb_hdr);
|
||||||
sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr));
|
sha_1_update(&file_sha1, (byte *)&sb_hdr, sizeof(sb_hdr));
|
||||||
write(fd, &sb_hdr, sizeof(sb_hdr));
|
write(fd, &sb_hdr, sizeof(sb_hdr));
|
||||||
|
|
||||||
|
memcpy(crypto_iv, &sb_hdr, 16);
|
||||||
|
|
||||||
/* update CBC-MACs */
|
/* update CBC-MACs */
|
||||||
for(int i = 0; i < g_nr_keys; i++)
|
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_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;
|
struct sb_key_dictionary_entry_t entry;
|
||||||
memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16);
|
memcpy(entry.hdr_cbc_mac, cbc_macs[i], 16);
|
||||||
cbc_mac(real_key, entry.key, sizeof(real_key) / BLOCK_SIZE, g_key_array[i],
|
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));
|
write(fd, &entry, sizeof(entry));
|
||||||
sha_1_update(&file_sha1, (byte *)&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 */
|
/* produce sections data */
|
||||||
for(int i = 0; i< sb_hdr.nr_sections; i++)
|
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);
|
produce_section_tag_cmd(&sb->sections[i], &tag_cmd, (i + 1) == sb_hdr.nr_sections);
|
||||||
if(g_nr_keys > 0)
|
if(g_nr_keys > 0)
|
||||||
cbc_mac((byte *)&tag_cmd, (byte *)&tag_cmd, sizeof(tag_cmd) / BLOCK_SIZE,
|
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));
|
sha_1_update(&file_sha1, (byte *)&tag_cmd, sizeof(tag_cmd));
|
||||||
write(fd, &tag_cmd, sizeof(tag_cmd));
|
write(fd, &tag_cmd, sizeof(tag_cmd));
|
||||||
/* produce other commands */
|
/* produce other commands */
|
||||||
byte cur_cbc_mac[16];
|
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++)
|
for(int j = 0; j < sb->sections[i].nr_insts; j++)
|
||||||
{
|
{
|
||||||
struct sb_inst_t *inst = &sb->sections[i].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);
|
sha_1_output(&file_sha1, final_sig);
|
||||||
generate_random_data(final_sig + 20, 12);
|
generate_random_data(final_sig + 20, 12);
|
||||||
if(g_nr_keys > 0)
|
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);
|
write(fd, final_sig, 32);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
|
||||||
|
|
@ -372,8 +372,10 @@ static void extract(unsigned long filesize)
|
||||||
|
|
||||||
if(memcmp(sb_header->signature, "STMP", 4) != 0)
|
if(memcmp(sb_header->signature, "STMP", 4) != 0)
|
||||||
bugp("Bad signature");
|
bugp("Bad signature");
|
||||||
|
/*
|
||||||
if(sb_header->image_size * BLOCK_SIZE > filesize)
|
if(sb_header->image_size * BLOCK_SIZE > filesize)
|
||||||
bugp("File size mismatch");
|
bugp("File size mismatch");
|
||||||
|
*/
|
||||||
if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t))
|
if(sb_header->header_size * BLOCK_SIZE != sizeof(struct sb_header_t))
|
||||||
bugp("Bad header size");
|
bugp("Bad header size");
|
||||||
if(sb_header->sec_hdr_size * BLOCK_SIZE != sizeof(struct sb_section_header_t))
|
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 */
|
/* sections */
|
||||||
if(strcasecmp(s_getenv("SB_RAW_CMD"), "YES") != 0)
|
if(strcasecmp(s_getenv("SB_RAW_CMD"), "YES") != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -615,10 +628,11 @@ static void extract(unsigned long filesize)
|
||||||
printf("Commands\n");
|
printf("Commands\n");
|
||||||
uint32_t offset = sb_header->first_boot_tag_off * BLOCK_SIZE;
|
uint32_t offset = sb_header->first_boot_tag_off * BLOCK_SIZE;
|
||||||
byte iv[16];
|
byte iv[16];
|
||||||
memcpy(iv, g_buf, 16);
|
|
||||||
const char *indent = " ";
|
const char *indent = " ";
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
/* restart with IV */
|
||||||
|
memcpy(iv, g_buf, 16);
|
||||||
byte cmd[BLOCK_SIZE];
|
byte cmd[BLOCK_SIZE];
|
||||||
if(sb_header->nr_keys > 0)
|
if(sb_header->nr_keys > 0)
|
||||||
cbc_mac(g_buf + offset, cmd, 1, real_key, iv, &iv, 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);
|
color(RED);
|
||||||
printf("NOOP\n");
|
printf("NOOP\n");
|
||||||
offset += BLOCK_SIZE;
|
offset += BLOCK_SIZE;
|
||||||
/* restart with IV */
|
|
||||||
memcpy(iv, g_buf, 16);
|
|
||||||
}
|
}
|
||||||
else if(hdr->opcode == SB_INST_TAG)
|
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)
|
if(tag->hdr.flags & SB_INST_LAST_TAG)
|
||||||
break;
|
break;
|
||||||
offset += size;
|
offset += size;
|
||||||
/* restart with IV */
|
|
||||||
memcpy(iv, g_buf, 16);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue