From c7f8b1833e7d352d628bcf0971eaec4d8cd31bc5 Mon Sep 17 00:00:00 2001 From: applestash Date: Mon, 22 Sep 2014 21:42:33 +1000 Subject: [PATCH] ctrtool: tmd savesize detection & smarter exheader pre check --- ctrtool/exheader.c | 18 ++++++++++++++++++ ctrtool/exheader.h | 3 +++ ctrtool/ncch.c | 3 ++- ctrtool/tmd.c | 10 +++++++++- ctrtool/tmd.h | 8 ++++++-- 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/ctrtool/exheader.c b/ctrtool/exheader.c index afb1927..6f064d9 100644 --- a/ctrtool/exheader.c +++ b/ctrtool/exheader.c @@ -42,6 +42,11 @@ void exheader_set_programid(exheader_context* ctx, u8 programid[8]) memcpy(ctx->programid, programid, 8); } +void exheader_set_hash(exheader_context* ctx, u8 hash[32]) +{ + memcpy(ctx->hash, hash, 32); +} + void exheader_set_counter(exheader_context* ctx, u8 counter[16]) { memcpy(ctx->counter, counter, 16); @@ -94,6 +99,19 @@ void exheader_read(exheader_context* ctx, u32 actions) } } +int exheader_hash_valid(exheader_context* ctx) +{ + u8 hash[32]; + ctr_sha_256((u8*)&ctx->header, 0x400, hash); + + if(memcmp(ctx->hash,hash,0x20)){ + fprintf(stderr, "Error, exheader hash mismatch. Wrong key?\n"); + return 0; + } + + return 1; +} + int exheader_programid_valid(exheader_context* ctx) { if (!settings_get_ignore_programid(ctx->usersettings)) diff --git a/ctrtool/exheader.h b/ctrtool/exheader.h index 6cebdeb..436a8d7 100644 --- a/ctrtool/exheader.h +++ b/ctrtool/exheader.h @@ -109,6 +109,7 @@ typedef struct settings* usersettings; u8 partitionid[8]; u8 programid[8]; + u8 hash[32]; u8 counter[16]; u8 key[16]; u32 offset; @@ -134,6 +135,7 @@ void exheader_set_size(exheader_context* ctx, u32 size); void exheader_set_partitionid(exheader_context* ctx, u8 partitionid[8]); void exheader_set_counter(exheader_context* ctx, u8 counter[16]); void exheader_set_programid(exheader_context* ctx, u8 programid[8]); +void exheader_set_hash(exheader_context* ctx, u8 hash[32]); void exheader_set_encrypted(exheader_context* ctx, u32 encrypted); void exheader_set_key(exheader_context* ctx, u8 key[16]); void exheader_set_usersettings(exheader_context* ctx, settings* usersettings); @@ -143,6 +145,7 @@ int exheader_process(exheader_context* ctx, u32 actions); const char* exheader_getvalidstring(int valid); void exheader_print(exheader_context* ctx); void exheader_verify(exheader_context* ctx); +int exheader_hash_valid(exheader_context* ctx); int exheader_programid_valid(exheader_context* ctx); void exheader_determine_key(exheader_context* ctx, u32 actions); diff --git a/ctrtool/ncch.c b/ctrtool/ncch.c index de2328d..f8e8dc2 100644 --- a/ctrtool/ncch.c +++ b/ctrtool/ncch.c @@ -328,6 +328,7 @@ void ncch_process(ncch_context* ctx, u32 actions) exheader_set_usersettings(&ctx->exheader, ctx->usersettings); exheader_set_partitionid(&ctx->exheader, ctx->header.partitionid); exheader_set_programid(&ctx->exheader, ctx->header.programid); + exheader_set_hash(&ctx->exheader, ctx->header.extendedheaderhash); exheader_set_counter(&ctx->exheader, exheadercounter); exheader_set_key(&ctx->exheader, ctx->key); exheader_set_encrypted(&ctx->exheader, ctx->encrypted); @@ -361,7 +362,7 @@ void ncch_process(ncch_context* ctx, u32 actions) if (result && ncch_get_exheader_size(ctx)) { - if (!exheader_programid_valid(&ctx->exheader)) + if (!exheader_hash_valid(&ctx->exheader)) return; result = exheader_process(&ctx->exheader, actions); diff --git a/ctrtool/tmd.c b/ctrtool/tmd.c index e6a2b15..8ba2dd2 100644 --- a/ctrtool/tmd.c +++ b/ctrtool/tmd.c @@ -86,6 +86,7 @@ void tmd_print(tmd_context* ctx) ctr_tmd_header_2048* header2048 = 0; ctr_tmd_body* body = 0; unsigned int contentcount = 0; + unsigned int savesize = 0; unsigned int i; if (type == TMD_RSA_2048_SHA256 || type == TMD_RSA_2048_SHA1) @@ -104,7 +105,8 @@ void tmd_print(tmd_context* ctx) body = tmd_get_body(ctx); contentcount = getbe16(body->contentcount); - + savesize = getle32(body->savedatasize); + fprintf(stdout, "\nTMD header:\n"); fprintf(stdout, "Signature type: %s\n", tmd_get_type_string(type)); fprintf(stdout, "Issuer: %s\n", body->issuer); @@ -115,6 +117,12 @@ void tmd_print(tmd_context* ctx) memdump(stdout, "Title id: ", body->titleid, 8); fprintf(stdout, "Title type: %08x\n", getbe32(body->titletype)); fprintf(stdout, "Group id: %04x\n", getbe16(body->groupid)); + if(savesize < sizeKB) + fprintf(stdout, "Save Size: %08x\n", savesize); + else if(savesize < sizeMB) + fprintf(stdout, "Save Size: %dKB (%08x)\n", savesize/sizeKB, savesize); + else + fprintf(stdout, "Save Size: %dMB (%08x)\n", savesize/sizeMB, savesize); fprintf(stdout, "Access rights: %08x\n", getbe32(body->accessrights)); fprintf(stdout, "Title version: %04x\n", getbe16(body->titleversion)); fprintf(stdout, "Content count: %04x\n", getbe16(body->contentcount)); diff --git a/ctrtool/tmd.h b/ctrtool/tmd.h index 5d9f475..6272429 100644 --- a/ctrtool/tmd.h +++ b/ctrtool/tmd.h @@ -27,12 +27,16 @@ typedef struct unsigned char titleid[8]; unsigned char titletype[4]; unsigned char groupid[2]; - unsigned char padding3[62]; + unsigned char savedatasize[4]; + unsigned char privsavedatasize[4]; + unsigned char padding3[4]; + unsigned char twlflag; + unsigned char padding4[0x31]; unsigned char accessrights[4]; unsigned char titleversion[2]; unsigned char contentcount[2]; unsigned char bootcontent[2]; - unsigned char padding4[2]; + unsigned char padding5[2]; unsigned char hash[32]; unsigned char contentinfo[36*64]; } ctr_tmd_body;