From 96960526e8208dc0bf0863309a4e1759b3ff444f Mon Sep 17 00:00:00 2001 From: applestash Date: Sat, 30 Aug 2014 12:34:24 +1000 Subject: [PATCH] refactored cia code an attempt make errors in tik/tmd values rarer in occurence --- makerom/cia.c | 36 +++++++++++++++++------------------- makerom/cia_build.h | 19 ++++++++++--------- makerom/tik.c | 30 ++++++++++++++++-------------- makerom/titleid.c | 10 ++++++++++ makerom/titleid.h | 3 +++ makerom/tmd.c | 11 ++++++----- 6 files changed, 62 insertions(+), 47 deletions(-) diff --git a/makerom/cia.c b/makerom/cia.c index 095fb28..07eefdf 100644 --- a/makerom/cia.c +++ b/makerom/cia.c @@ -166,7 +166,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset) ciaset->content.includeUpdateNcch = usrset->cia.includeUpdateNcch; ciaset->verbose = usrset->common.verbose; - u32_to_u8(ciaset->tmd.titleType,TYPE_CTR,BE); + ciaset->tmd.titleType = TYPE_CTR; ciaset->content.encryptCia = usrset->common.rsfSet.Option.EnableCrypt; ciaset->content.IsDlc = usrset->cia.DlcContent; if(ciaset->keys->aes.commonKey[ciaset->keys->aes.currentCommonKey] == NULL && ciaset->content.encryptCia){ @@ -182,10 +182,10 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset) } // Ticket Data - rndset(ciaset->tik.ticketId,8); - u32_to_u8(ciaset->tik.deviceId,usrset->cia.deviceId,BE); - u32_to_u8(ciaset->tik.eshopAccId,usrset->cia.eshopAccId,BE); - ciaset->tik.licenceType = 0; + ciaset->tik.ticketId = u64GetRand(); + ciaset->tik.deviceId = usrset->cia.deviceId; + ciaset->tik.eshopAccId = usrset->cia.eshopAccId; + ciaset->tik.licenceType = lic_Permanent; ciaset->tik.audit = 0; if(usrset->cia.randomTitleKey) @@ -208,6 +208,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset) ciaset->content.id[0] = usrset->cia.contentId[0]; ciaset->tmd.formatVersion = 1; + ciaset->tmd.accessRights = 0; result = GenCertChildIssuer(ciaset->tmd.issuer,ciaset->keys->certs.cpCert); return 0; } @@ -256,7 +257,7 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset) } /* Gen Settings From Ncch0 */ - endian_memcpy(ciaset->common.titleId,hdr->titleId,8,LE); + ciaset->common.titleId = u8_to_u64(hdr->titleId,LE); /* Getting ncch key */ @@ -289,19 +290,17 @@ int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 * memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr)); if(key != NULL) CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx,key,ncch_exhdr); - - u16 Category = u8_to_u16((ciaset->common.titleId+2),BE); - if(IsPatch(Category)||ciaset->content.IsCfa||ciaset->content.keyNotFound) - u32_to_u8(ciaset->tmd.savedataSize,0,LE); - else - u32_to_u8(ciaset->tmd.savedataSize,(u32)GetSaveDataSize_frm_exhdr(exhdr),LE); - if(ciaset->rsf->SystemControlInfo.SaveDataSize && !ciaset->content.IsCfa && ciaset->content.keyNotFound){ + if(IsPatch(GetTidCategory(ciaset->common.titleId))||ciaset->content.IsCfa) + ciaset->tmd.savedataSize = 0; + else if(ciaset->content.keyNotFound && ciaset->rsf->SystemControlInfo.SaveDataSize){ // if it's a title which can have save data, but save data size could not be read from exhdr u64 size = 0; GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA"); - u32_to_u8(ciaset->tmd.savedataSize,(u32)size,LE); + ciaset->tmd.savedataSize = (u32)(size & MAX_U32); } - + else + ciaset->tmd.savedataSize = (u32)(GetSaveDataSize_frm_exhdr(exhdr) & MAX_U32); + if(ciaset->content.IsCfa||ciaset->content.keyNotFound){ if(ciaset->common.titleVersion[VER_MAJOR] == MAX_U16){ // '-major' wasn't set if(ciaset->content.IsCfa){ // Is a CFA and can be decrypted @@ -479,8 +478,7 @@ int GetSettingsFromSrl(cia_settings *ciaset) } // Generate and store Converted TitleID - u64_to_u8(ciaset->common.titleId,ConvertTwlIdToCtrId(u8_to_u64(hdr->title_id,LE)),BE); - //memdump(stdout,"SRL TID: ",ciaset->TitleID,8); + ciaset->common.titleId = ConvertTwlIdToCtrId(u8_to_u64(hdr->title_id,LE)); // Get TWL Flag ciaset->tmd.twlFlag = ((hdr->reserved_flags[3] & 6) >> 1); @@ -491,8 +489,8 @@ int GetSettingsFromSrl(cia_settings *ciaset) ciaset->tmd.version = version; // Get SaveDataSize (Public and Private) - memcpy(ciaset->tmd.savedataSize,hdr->pubSaveDataSize,4); - memcpy(ciaset->tmd.privSavedataSize,hdr->privSaveDataSize,4); + ciaset->tmd.savedataSize = u8_to_u32(hdr->pubSaveDataSize,LE); + ciaset->tmd.privSavedataSize = u8_to_u32(hdr->privSaveDataSize,LE); // Setting CIA Content Settings ciaset->content.count = 1; diff --git a/makerom/cia_build.h b/makerom/cia_build.h index a33717d..ad0de78 100644 --- a/makerom/cia_build.h +++ b/makerom/cia_build.h @@ -23,7 +23,7 @@ typedef struct bool verbose; struct{ - u8 titleId[8]; + u64 titleId; u16 titleVersion[4]; u8 titleKey[16]; } common; @@ -39,12 +39,12 @@ typedef struct u8 formatVersion; u16 version; - - u8 ticketId[8]; - u8 deviceId[4]; + + u64 ticketId; + u32 deviceId; u8 licenceType; u8 audit; - u8 eshopAccId[4]; + u32 eshopAccId; } tik; struct{ @@ -52,10 +52,11 @@ typedef struct u8 formatVersion; u16 version; - - u8 titleType[4]; - u8 savedataSize[4]; - u8 privSavedataSize[4]; + u32 accessRights; + + u32 titleType; + u32 savedataSize; + u32 privSavedataSize; u8 twlFlag; } tmd; diff --git a/makerom/tik.c b/makerom/tik.c index 5f2e233..db1f974 100644 --- a/makerom/tik.c +++ b/makerom/tik.c @@ -50,24 +50,26 @@ int SetupTicketBuffer(cia_settings *set) void SetupTicketHeader(tik_hdr *hdr, cia_settings *ciaset) { clrmem(hdr,sizeof(tik_hdr)); - + memcpy(hdr->issuer,ciaset->tik.issuer,0x40); hdr->formatVersion = ciaset->tik.formatVersion; hdr->caCrlVersion = ciaset->cert.caCrlVersion; hdr->signerCrlVersion = ciaset->cert.signerCrlVersion; - if(ciaset->content.encryptCia) - CryptTitleKey(hdr->encryptedTitleKey, ciaset->common.titleKey,ciaset->common.titleId,ciaset->keys,ENC); - else - rndset(hdr->encryptedTitleKey,16); - memcpy(hdr->ticketId,ciaset->tik.ticketId,8); - memcpy(hdr->deviceId,ciaset->tik.deviceId,4); - memcpy(hdr->titleId,ciaset->common.titleId,8); + u64_to_u8(hdr->ticketId,ciaset->tik.ticketId,BE); + u32_to_u8(hdr->deviceId,ciaset->tik.deviceId,BE); + u64_to_u8(hdr->titleId,ciaset->common.titleId,BE); u16_to_u8(hdr->ticketVersion,ciaset->tik.version,BE); hdr->licenceType = ciaset->tik.licenceType; hdr->keyId = ciaset->keys->aes.currentCommonKey; - memcpy(hdr->eshopAccId,ciaset->tik.eshopAccId,4); + u32_to_u8(hdr->eshopAccId,ciaset->tik.eshopAccId,BE); hdr->audit = ciaset->tik.audit; SetLimits(hdr,ciaset); + + // Crypt TitleKey + if(ciaset->content.encryptCia) + CryptTitleKey(hdr->encryptedTitleKey, ciaset->common.titleKey, hdr->titleId, ciaset->keys, ENC); + else + rndset(hdr->encryptedTitleKey,AES_128_KEY_SIZE); } int SignTicketHeader(buffer_struct *tik, keys_struct *keys) @@ -83,12 +85,12 @@ int SignTicketHeader(buffer_struct *tik, keys_struct *keys) return ctr_sig(data,len,sig->data,keys->rsa.xsPub,keys->rsa.xsPvt,RSA_2048_SHA256,CTR_RSA_SIGN); } -int CryptTitleKey(u8 *EncTitleKey, u8 *DecTitleKey, u8 *TitleID, keys_struct *keys, u8 mode) +int CryptTitleKey(u8 *encKey, u8 *decKey, u8 *titleId, keys_struct *keys, u8 mode) { //Generating IV u8 iv[16]; memset(&iv,0x0,16); - memcpy(iv,TitleID,0x8); + memcpy(iv,titleId,0x8); //Setting up Aes Context ctr_aes_context ctx; @@ -96,9 +98,9 @@ int CryptTitleKey(u8 *EncTitleKey, u8 *DecTitleKey, u8 *TitleID, keys_struct *ke //Crypting TitleKey ctr_init_aes_cbc(&ctx,keys->aes.commonKey[keys->aes.currentCommonKey],iv,mode); - if(mode == ENC) ctr_aes_cbc(&ctx,DecTitleKey,EncTitleKey,0x10,ENC); - else ctr_aes_cbc(&ctx,EncTitleKey,DecTitleKey,0x10,DEC); - + if(mode == ENC) ctr_aes_cbc(&ctx,decKey,encKey,0x10,ENC); + else ctr_aes_cbc(&ctx,encKey,decKey,0x10,DEC); + // Return return 0; } diff --git a/makerom/titleid.c b/makerom/titleid.c index d4479c4..b904534 100644 --- a/makerom/titleid.c +++ b/makerom/titleid.c @@ -14,6 +14,16 @@ u64 ConvertTwlIdToCtrId(u64 pgid) return 0x0004800000000000 | (pgid & 0x00007FFFFFFFFFFF); } +u16 GetTidCategory(u64 titleId) +{ + return (titleId>>32) & MAX_U16; +} + +u32 GetTidUniqueId(u64 titleId) +{ + return (titleId>>8) & 0xFFFFFF; +} + int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader) { int ret; diff --git a/makerom/titleid.h b/makerom/titleid.h index ecfd782..8f96d53 100644 --- a/makerom/titleid.h +++ b/makerom/titleid.h @@ -88,6 +88,9 @@ u64 ConvertTwlIdToCtrId(u64 pgid); int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader); int GetUniqueID(u32 *dest, rsf_settings *rsf); +u16 GetTidCategory(u64 titleId); +u32 GetTidUniqueId(u64 titleId); + bool IsDemo(u16 Category); bool IsSystem(u16 Category); bool IsDlpChild(u16 Category); diff --git a/makerom/tmd.c b/makerom/tmd.c index e81f668..6abb6e5 100644 --- a/makerom/tmd.c +++ b/makerom/tmd.c @@ -54,11 +54,12 @@ int SetupTMDHeader(tmd_hdr *hdr, tmd_content_info_record *info_record, cia_setti hdr->formatVersion = ciaset->tmd.formatVersion; hdr->caCrlVersion = ciaset->cert.caCrlVersion; hdr->signerCrlVersion = ciaset->cert.signerCrlVersion; - memcpy(hdr->titleID,ciaset->common.titleId,8); - memcpy(hdr->titleType,ciaset->tmd.titleType,4); - memcpy(hdr->savedataSize,ciaset->tmd.savedataSize,4); - memcpy(hdr->privSavedataSize,ciaset->tmd.privSavedataSize,4); + u64_to_u8(hdr->titleID,ciaset->common.titleId,BE); + u32_to_u8(hdr->titleType,ciaset->tmd.titleType,BE); + u32_to_u8(hdr->savedataSize,ciaset->tmd.savedataSize,LE); + u32_to_u8(hdr->privSavedataSize,ciaset->tmd.privSavedataSize,LE); hdr->twlFlag = ciaset->tmd.twlFlag; + u32_to_u8(hdr->accessRights,ciaset->tmd.accessRights,BE); u16_to_u8(hdr->titleVersion,ciaset->tmd.version,BE); u16_to_u8(hdr->contentCount,ciaset->content.count,BE); ctr_sha(info_record,sizeof(tmd_content_info_record)*64,hdr->infoRecordHash,CTR_SHA_256); @@ -129,7 +130,7 @@ u64 GetTmdTitleId(tmd_hdr *hdr) u32 GetTmdSaveSize(tmd_hdr *hdr) { - return u8_to_u32(hdr->savedataSize,BE); + return u8_to_u32(hdr->savedataSize,LE); } u16 GetTmdContentCount(tmd_hdr *hdr)