From dc8de388a31e1a957a072873ff33879864c9d7b0 Mon Sep 17 00:00:00 2001 From: applestash Date: Sat, 21 Jun 2014 18:21:22 +1000 Subject: [PATCH] Fixed some errors and bad programming --- makerom/accessdesc.c | 153 ++++++++++++++++++------------------ makerom/accessdesc.h | 2 +- makerom/cia.c | 27 +++---- makerom/cia.h | 2 +- makerom/dir.c | 2 +- makerom/exheader.c | 59 ++++++-------- makerom/exheader.h | 26 ++++--- makerom/keyset.c | 45 +++++++---- makerom/keyset.h | 2 +- makerom/ncch.c | 179 ++++++++++++++++++++----------------------- makerom/ncch.h | 8 +- 11 files changed, 246 insertions(+), 259 deletions(-) diff --git a/makerom/accessdesc.c b/makerom/accessdesc.c index 8de7884..7247ab6 100644 --- a/makerom/accessdesc.c +++ b/makerom/accessdesc.c @@ -15,57 +15,57 @@ const int RSF_RSA_DATA_LEN = 344; const int RSF_DESC_DATA_LEN = 684; -int accessdesc_SignWithKey(exheader_settings *exhdrset, ncch_settings *ncchset); -int accessdesc_GetSignFromRsf(exheader_settings *exhdrset, ncch_settings *ncchset); -int accessdesc_GetSignFromPreset(exheader_settings *exhdrset, ncch_settings *ncchset); -void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_settings *ncchset); +int accessdesc_SignWithKey(exheader_settings *exhdrset); +int accessdesc_GetSignFromRsf(exheader_settings *exhdrset); +int accessdesc_GetSignFromPreset(exheader_settings *exhdrset); +void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, keys_struct *keys); #ifndef PUBLIC_BUILD -void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, ncch_settings *ncchset); +void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, keys_struct *keys); #endif bool IsValidB64Char(char chr); u32 b64_strlen(char *str); void b64_strcpy(char *dst, char *src); -int set_AccessDesc(exheader_settings *exhdrset, ncch_settings *ncchset) +int set_AccessDesc(exheader_settings *exhdrset) { if(exhdrset->useAccessDescPreset) - return accessdesc_GetSignFromPreset(exhdrset,ncchset); - else if(ncchset->rsfSet->CommonHeaderKey.Found) // Keydata exists in RSF - return accessdesc_GetSignFromRsf(exhdrset,ncchset); - else if(!ncchset->keys->rsa.requiresPresignedDesc) // Else if The AccessDesc can be signed with key - return accessdesc_SignWithKey(exhdrset,ncchset); + return accessdesc_GetSignFromPreset(exhdrset); + else if(exhdrset->rsf->CommonHeaderKey.Found) // Keydata exists in RSF + return accessdesc_GetSignFromRsf(exhdrset); + else if(!exhdrset->keys->rsa.requiresPresignedDesc) // Else if The AccessDesc can be signed with key + return accessdesc_SignWithKey(exhdrset); else{ // No way the access desc signature can be 'obtained' fprintf(stderr,"[EXHEADER ERROR] Current keyset cannot sign AccessDesc, please appropriatly setup RSF, or specify a preset with -accessdesc\n"); return CANNOT_SIGN_ACCESSDESC; } } -int accessdesc_SignWithKey(exheader_settings *exhdrset, ncch_settings *ncchset) +int accessdesc_SignWithKey(exheader_settings *exhdrset) { /* Set RSA Keys */ memcpy(exhdrset->keys->rsa.cxiHdrPvt,exhdrset->keys->rsa.cciCfaPvt,0x100); memcpy(exhdrset->keys->rsa.cxiHdrPub,exhdrset->keys->rsa.cciCfaPub,0x100); - memcpy(&exhdrset->exHdr->accessDescriptor.ncchRsaPubKey,exhdrset->keys->rsa.cxiHdrPub,0x100); + memcpy(&exhdrset->acexDesc->ncchRsaPubKey,exhdrset->keys->rsa.cxiHdrPub,0x100); /* Copy Data From ExHeader */ - memcpy(&exhdrset->exHdr->accessDescriptor.arm11SystemLocalCapabilities,&exhdrset->exHdr->arm11SystemLocalCapabilities,sizeof(exhdr_ARM11SystemLocalCapabilities)); - memcpy(&exhdrset->exHdr->accessDescriptor.arm11KernelCapabilities,&exhdrset->exHdr->arm11KernelCapabilities,sizeof(exhdr_ARM11KernelCapabilities)); - memcpy(&exhdrset->exHdr->accessDescriptor.arm9AccessControlInfo,&exhdrset->exHdr->arm9AccessControlInfo,sizeof(exhdr_ARM9AccessControlInfo)); + memcpy(&exhdrset->acexDesc->arm11SystemLocalCapabilities,&exhdrset->exHdr->arm11SystemLocalCapabilities,sizeof(exhdr_ARM11SystemLocalCapabilities)); + memcpy(&exhdrset->acexDesc->arm11KernelCapabilities,&exhdrset->exHdr->arm11KernelCapabilities,sizeof(exhdr_ARM11KernelCapabilities)); + memcpy(&exhdrset->acexDesc->arm9AccessControlInfo,&exhdrset->exHdr->arm9AccessControlInfo,sizeof(exhdr_ARM9AccessControlInfo)); /* Adjust Data */ - u8 *flag = &exhdrset->exHdr->accessDescriptor.arm11SystemLocalCapabilities.flag; + u8 *flag = &exhdrset->acexDesc->arm11SystemLocalCapabilities.flag; u8 SystemMode = (*flag>>4)&0xF; u8 AffinityMask = (*flag>>2)&0x3; u8 IdealProcessor = 1<<((*flag>>0)&0x3); *flag = (u8)(SystemMode << 4 | AffinityMask << 2 | IdealProcessor); - exhdrset->exHdr->accessDescriptor.arm11SystemLocalCapabilities.priority /= 2; + exhdrset->acexDesc->arm11SystemLocalCapabilities.priority /= 2; /* Sign AccessDesc */ - return SignAccessDesc(exhdrset->exHdr,exhdrset->keys); + return SignAccessDesc(exhdrset->acexDesc,exhdrset->keys); } -int accessdesc_GetSignFromRsf(exheader_settings *exhdrset, ncch_settings *ncchset) +int accessdesc_GetSignFromRsf(exheader_settings *exhdrset) { /* Yaml Option Sanity Checks */ if(!exhdrset->rsf->CommonHeaderKey.Found){ @@ -127,14 +127,14 @@ int accessdesc_GetSignFromRsf(exheader_settings *exhdrset, ncch_settings *ncchse /* Set AccessDesc */ out = 0x100; - result = base64_decode(exhdrset->exHdr->accessDescriptor.signature,(size_t *)&out,(const u8*)exhdrset->rsf->CommonHeaderKey.AccCtlDescSign, strlen( exhdrset->rsf->CommonHeaderKey.AccCtlDescSign)); + result = base64_decode(exhdrset->acexDesc->signature,(size_t *)&out,(const u8*)exhdrset->rsf->CommonHeaderKey.AccCtlDescSign, strlen( exhdrset->rsf->CommonHeaderKey.AccCtlDescSign)); if(out != 0x100) result = POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL; if(result) goto finish; - memcpy(exhdrset->exHdr->accessDescriptor.ncchRsaPubKey,exhdrset->keys->rsa.cxiHdrPub,0x100); + memcpy(exhdrset->acexDesc->ncchRsaPubKey,exhdrset->keys->rsa.cxiHdrPub,0x100); out = 0x200; - result = base64_decode((u8*)&exhdrset->exHdr->accessDescriptor.arm11SystemLocalCapabilities,(size_t *)&out,(const u8*)exhdrset->rsf->CommonHeaderKey.AccCtlDescBin,strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescBin)); + result = base64_decode((u8*)&exhdrset->acexDesc->arm11SystemLocalCapabilities,(size_t *)&out,(const u8*)exhdrset->rsf->CommonHeaderKey.AccCtlDescBin,strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescBin)); if(out != 0x200) result = POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL; if(result) goto finish; @@ -142,7 +142,7 @@ finish: return result; } -int accessdesc_GetSignFromPreset(exheader_settings *exhdrset, ncch_settings *ncchset) +int accessdesc_GetSignFromPreset(exheader_settings *exhdrset) { u8 *desc = NULL; u8 *accessDesc = NULL; @@ -152,9 +152,9 @@ int accessdesc_GetSignFromPreset(exheader_settings *exhdrset, ncch_settings *ncc u8 *cxiPubk = NULL; u8 *cxiPvtk = NULL; - accessdesc_GetPresetData(&desc,&accessDesc,&depList,ncchset); + accessdesc_GetPresetData(&desc,&accessDesc,&depList,exhdrset->keys); #ifndef PUBLIC_BUILD - accessdesc_GetPresetSigData(&accessDescSig,&cxiPubk,&cxiPvtk,ncchset); + accessdesc_GetPresetSigData(&accessDescSig,&cxiPubk,&cxiPvtk,exhdrset->keys); #endif // Error Checking @@ -163,11 +163,12 @@ int accessdesc_GetSignFromPreset(exheader_settings *exhdrset, ncch_settings *ncc return CANNOT_SIGN_ACCESSDESC; } - if((!cxiPubk || !cxiPvtk || !accessDesc || !accessDescSig) && ncchset->keys->rsa.requiresPresignedDesc){ + if((!cxiPubk || !cxiPvtk || !accessDesc || !accessDescSig) && exhdrset->keys->rsa.requiresPresignedDesc){ fprintf(stderr,"[EXHEADER ERROR] This AccessDesc preset needs to be signed, the current keyset is incapable of doing so. Please configure RSF file with the appropriate signature data.\n"); return CANNOT_SIGN_ACCESSDESC; } + // Setting data in Exheader // Dependency List memcpy(exhdrset->exHdr->dependencyList,depList,0x180); @@ -191,23 +192,23 @@ int accessdesc_GetSignFromPreset(exheader_settings *exhdrset, ncch_settings *ncc // Setting AccessDesc Area // Signing normally if possible - if(!ncchset->keys->rsa.requiresPresignedDesc) - return accessdesc_SignWithKey(exhdrset,ncchset); + if(!exhdrset->keys->rsa.requiresPresignedDesc) + return accessdesc_SignWithKey(exhdrset); // Otherwise set static data & ncch hdr sig info memcpy(exhdrset->keys->rsa.cxiHdrPub,cxiPubk,0x100); memcpy(exhdrset->keys->rsa.cxiHdrPvt,cxiPvtk,0x100); - memcpy(&exhdrset->exHdr->accessDescriptor.signature,accessDescSig,0x100); - memcpy(&exhdrset->exHdr->accessDescriptor.ncchRsaPubKey,cxiPubk,0x100); - memcpy(&exhdrset->exHdr->accessDescriptor.arm11SystemLocalCapabilities,accessDesc,0x200); + memcpy(&exhdrset->acexDesc->signature,accessDescSig,0x100); + memcpy(&exhdrset->acexDesc->ncchRsaPubKey,cxiPubk,0x100); + memcpy(&exhdrset->acexDesc->arm11SystemLocalCapabilities,accessDesc,0x200); return 0; } -void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_settings *ncchset) +void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, keys_struct *keys) { - if(ncchset->keys->accessDescSign.presetType == desc_preset_APP){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + if(keys->accessDescSign.presetType == desc_preset_APP){ + switch(keys->accessDescSign.targetFirmware){ case 0x1B: case 0x1C: *desc = (u8*)app_fw1B_desc_data; @@ -247,8 +248,8 @@ void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_set } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_EC_APP){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_EC_APP){ + switch(keys->accessDescSign.targetFirmware){ case 0x20: *desc = (u8*)ecapp_fw20_desc_data; *accessDesc = (u8*)ecapp_fw20_acex_data; @@ -261,8 +262,8 @@ void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_set break; } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_DLP){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_DLP){ + switch(keys->accessDescSign.targetFirmware){ case 0x1B: case 0x1C: *desc = (u8*)dlp_fw1B_desc_data; @@ -281,8 +282,8 @@ void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_set break; } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_DEMO){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_DEMO){ + switch(keys->accessDescSign.targetFirmware){ case 0x1E: *desc = (u8*)demo_fw1E_desc_data; *accessDesc = (u8*)demo_fw1E_acex_data; @@ -295,8 +296,8 @@ void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_set break; } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_FIRM){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_FIRM){ + switch(keys->accessDescSign.targetFirmware){ default: *desc = (u8*)firm_fw26_desc_data; *accessDesc = (u8*)firm_fw26_acex_data; @@ -307,75 +308,75 @@ void accessdesc_GetPresetData(u8 **desc, u8 **accessDesc, u8 **depList, ncch_set } #ifndef PUBLIC_BUILD -void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, ncch_settings *ncchset) +void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, keys_struct *keys) { - if(ncchset->keys->accessDescSign.presetType == desc_preset_APP){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + if(keys->accessDescSign.presetType == desc_preset_APP){ + switch(keys->accessDescSign.targetFirmware){ case 0x1B: case 0x1C: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)app_fw1B_dev_acexsig; *cxiPubk = (u8*)app_fw1B_dev_hdrpub; *cxiPvtk = (u8*)app_fw1B_dev_hdrpvt; } break; case 0x1D: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)app_fw1D_dev_acexsig; *cxiPubk = (u8*)app_fw1D_dev_hdrpub; *cxiPvtk = (u8*)app_fw1D_dev_hdrpvt; } - if(ncchset->keys->keyset == pki_PRODUCTION){ + if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)app_fw1D_prod_acexsig; *cxiPubk = (u8*)app_fw1D_prod_hdrpub; *cxiPvtk = NULL; } break; case 0x1E: - if(ncchset->keys->keyset == pki_PRODUCTION){ + if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)app_fw1E_prod_acexsig; *cxiPubk = (u8*)app_fw1E_prod_hdrpub; *cxiPvtk = NULL; } break; case 0x20: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)app_fw20_dev_acexsig; *cxiPubk = (u8*)app_fw20_dev_hdrpub; *cxiPvtk = NULL; } - else if(ncchset->keys->keyset == pki_PRODUCTION){ + else if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)app_fw20_prod_acexsig; *cxiPubk = (u8*)app_fw20_prod_hdrpub; *cxiPvtk = NULL; } break; case 0x21: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)app_fw21_dev_acexsig; *cxiPubk = (u8*)app_fw21_dev_hdrpub; *cxiPvtk = (u8*)app_fw21_dev_hdrpvt; } - else if(ncchset->keys->keyset == pki_PRODUCTION){ + else if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)app_fw21_prod_acexsig; *cxiPubk = (u8*)app_fw21_prod_hdrpub; *cxiPvtk = NULL; } break; case 0x23: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)app_fw23_dev_acexsig; *cxiPubk = (u8*)app_fw23_dev_hdrpub; *cxiPvtk = NULL; } - else if(ncchset->keys->keyset == pki_PRODUCTION){ + else if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)app_fw23_prod_acexsig; *cxiPubk = (u8*)app_fw23_prod_hdrpub; *cxiPvtk = NULL; } break; case 0x27: - if(ncchset->keys->keyset == pki_PRODUCTION){ + if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)app_fw27_prod_acexsig; *cxiPubk = (u8*)app_fw27_prod_hdrpub; *cxiPvtk = NULL; @@ -384,17 +385,17 @@ void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_EC_APP){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_EC_APP){ + switch(keys->accessDescSign.targetFirmware){ case 0x20: - if(ncchset->keys->keyset == pki_PRODUCTION){ + if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)ecapp_fw20_prod_acexsig; *cxiPubk = (u8*)ecapp_fw20_prod_hdrpub; *cxiPvtk = NULL; } break; case 0x23: - if(ncchset->keys->keyset == pki_PRODUCTION){ + if(keys->keyset == pki_PRODUCTION){ *accessDescSig = (u8*)ecapp_fw23_prod_acexsig; *cxiPubk = (u8*)ecapp_fw23_prod_hdrpub; *cxiPvtk = NULL; @@ -402,25 +403,25 @@ void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, break; } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_DLP){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_DLP){ + switch(keys->accessDescSign.targetFirmware){ case 0x1B: case 0x1C: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)dlp_fw1B_dev_acexsig; *cxiPubk = (u8*)dlp_fw1B_dev_hdrpub; *cxiPvtk = (u8*)dlp_fw1B_dev_hdrpvt; } break; case 0x1D: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)dlp_fw1D_dev_acexsig; *cxiPubk = (u8*)dlp_fw1D_dev_hdrpub; *cxiPvtk = (u8*)dlp_fw1D_dev_hdrpvt; } break; case 0x21: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)dlp_fw21_dev_acexsig; *cxiPubk = (u8*)dlp_fw21_dev_hdrpub; *cxiPvtk = (u8*)dlp_fw21_dev_hdrpvt; @@ -428,17 +429,17 @@ void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, break; } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_DEMO){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_DEMO){ + switch(keys->accessDescSign.targetFirmware){ case 0x1E: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)demo_fw1E_dev_acexsig; *cxiPubk = (u8*)demo_fw1E_dev_hdrpub; *cxiPvtk = NULL; } break; case 0x21: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)demo_fw21_dev_acexsig; *cxiPubk = (u8*)demo_fw21_dev_hdrpub; *cxiPvtk = (u8*)demo_fw21_dev_hdrpvt; @@ -446,10 +447,10 @@ void accessdesc_GetPresetSigData(u8 **accessDescSig, u8 **cxiPubk, u8 **cxiPvtk, break; } } - else if(ncchset->keys->accessDescSign.presetType == desc_preset_FIRM){ - switch(ncchset->keys->accessDescSign.targetFirmware){ + else if(keys->accessDescSign.presetType == desc_preset_FIRM){ + switch(keys->accessDescSign.targetFirmware){ case 0x26: - if(ncchset->keys->keyset == pki_DEVELOPMENT){ + if(keys->keyset == pki_DEVELOPMENT){ *accessDescSig = (u8*)firm_fw26_dev_acexsig; *cxiPubk = (u8*)firm_fw26_dev_hdrpub; *cxiPvtk = NULL; @@ -492,6 +493,6 @@ void b64_strcpy(char *dst, char *src) } dst[j] = 0; - memdump(stdout,"src: ",(u8*)src,src_len+1); - memdump(stdout,"dst: ",(u8*)dst,j+1); -} + //memdump(stdout,"src: ",(u8*)src,src_len+1); + //memdump(stdout,"dst: ",(u8*)dst,j+1); +} \ No newline at end of file diff --git a/makerom/accessdesc.h b/makerom/accessdesc.h index c3324f4..a5f01f2 100644 --- a/makerom/accessdesc.h +++ b/makerom/accessdesc.h @@ -1,3 +1,3 @@ #pragma once -int set_AccessDesc(exheader_settings *exhdrset, ncch_settings *ncchset); \ No newline at end of file +int set_AccessDesc(exheader_settings *exhdrset); \ No newline at end of file diff --git a/makerom/cia.c b/makerom/cia.c index 30df01d..55967dc 100644 --- a/makerom/cia.c +++ b/makerom/cia.c @@ -160,6 +160,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset) { // General Stuff ciaset->keys = &usrset->common.keys; + ciaset->rsf = &usrset->common.rsfSet; ciaset->ciaSections.content.buffer = usrset->common.workingFile.buffer; ciaset->ciaSections.content.size = usrset->common.workingFile.size; usrset->common.workingFile.buffer = NULL; @@ -180,8 +181,6 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset) ciaset->common.titleVersion[i] = usrset->cia.titleVersion[i]; } - ciaset->content.overrideSaveDataSize = usrset->cia.overideSaveDataSize; - // Ticket Data u64_to_u8(ciaset->tik.ticketId,u64GetRand(),BE); if(usrset->cia.randomTitleKey) @@ -264,9 +263,7 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset) u8 *ncchkey = NULL; if(!ciaset->content.keyNotFound){ SetNcchUnfixedKeys(ciaset->keys,ncch0); - ncchkey = GetNCCHKey(keyType,ciaset->keys); - if(keyType == KeyIsUnFixed2) - ncchkey = GetNCCHKey(KeyIsUnFixed,ciaset->keys); + ncchkey = GetNCCHKey0(keyType,ciaset->keys); } /* Get TMD Data from ncch */ @@ -289,11 +286,14 @@ int GetCIADataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 CryptNCCHSection((u8*)exhdr,0x400,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->content.overrideSaveDataSize){ + 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){ u64 size = 0; - GetSaveDataSizeFromString(&size,ciaset->content.overrideSaveDataSize,"CIA"); + GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA"); u32_to_u8(ciaset->tmd.savedataSize,(u32)size,LE); } @@ -524,14 +524,9 @@ int GetSettingsFromCci(cia_settings *ciaset) u64 cciContentOffsets[CCI_MAX_CONTENT]; cciContentOffsets[0] = ncch0_offset; - ncch_hdr *hdr; for(int i = 1; i < 8; i++){ if(GetPartitionSize(ciaset->ciaSections.content.buffer,i)){ cciContentOffsets[j] = GetPartitionOffset(ciaset->ciaSections.content.buffer,i); - - // Get Data from ncch HDR - GetNCCH_CommonHDR(hdr,NULL,GetPartition(ciaset->ciaSections.content.buffer,i)); - hdr = (ncch_hdr*)(ciaset->ciaSections.content.buffer + cciContentOffsets[j] + 0x100); // Get Size ciaset->content.size[j] = GetPartitionSize(ciaset->ciaSections.content.buffer,i); @@ -540,9 +535,7 @@ int GetSettingsFromCci(cia_settings *ciaset) ciaset->content.totalSize += ciaset->content.size[j]; // Get ID - u8 hash[0x20]; - ctr_sha((u8*)hdr,0x200,hash,CTR_SHA_256); - ciaset->content.id[j] = u8_to_u32(hash,BE); + ciaset->content.id[j] = u32GetRand(); // Get Index ciaset->content.index[j] = i; diff --git a/makerom/cia.h b/makerom/cia.h index ce59bd1..57bc0ba 100644 --- a/makerom/cia.h +++ b/makerom/cia.h @@ -40,6 +40,7 @@ typedef struct FILE *out; + rsf_settings *rsf; keys_struct *keys; struct{ @@ -83,7 +84,6 @@ typedef struct bool IsCfa; bool IsDlc; bool encryptCia; - char *overrideSaveDataSize; bool keyNotFound; diff --git a/makerom/dir.c b/makerom/dir.c index 2c2e0b4..bcd57b2 100644 --- a/makerom/dir.c +++ b/makerom/dir.c @@ -324,4 +324,4 @@ void fs_FreeFiles(fs_dir *dir) fs_dir *tmp = (fs_dir*)dir->dir; for(u32 i = 0; i < dir->u_dir; i++) fs_FreeFiles(&tmp[i]); -} +} \ No newline at end of file diff --git a/makerom/exheader.c b/makerom/exheader.c index 72391ec..0270b35 100644 --- a/makerom/exheader.c +++ b/makerom/exheader.c @@ -6,10 +6,9 @@ /* Prototypes */ -void init_ExHeaderSettings(exheader_settings *exhdrset); void free_ExHeaderSettings(exheader_settings *exhdrset); int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings *ncchset); -int get_ExHeaderSettingsFromYaml(exheader_settings *exhdrset); +int get_ExHeaderSettingsFromRsf(exheader_settings *exhdrset); int get_ExHeaderCodeSetInfo(exhdr_CodeSetInfo *CodeSetInfo, rsf_settings *rsf); int get_ExHeaderDependencyList(u8 *DependencyList, rsf_settings *rsf); @@ -52,17 +51,17 @@ u32 GetDescPrefixBits(int numPrefixBits, u32 PrefixVal); int get_ExHeaderARM9AccessControlInfo(exhdr_ARM9AccessControlInfo *arm9, rsf_settings *rsf); /* ExHeader Signature Functions */ -int SignAccessDesc(extended_hdr *exHdr, keys_struct *keys) +int SignAccessDesc(access_descriptor *acexDesc, keys_struct *keys) { - u8 *AccessDesc = (u8*) &exHdr->accessDescriptor.ncchRsaPubKey; - u8 *Signature = (u8*) &exHdr->accessDescriptor.signature; + u8 *AccessDesc = (u8*) &acexDesc->ncchRsaPubKey; + u8 *Signature = (u8*) &acexDesc->signature; return ctr_sig(AccessDesc,0x300,Signature,keys->rsa.acexPub,keys->rsa.acexPvt,RSA_2048_SHA256,CTR_RSA_SIGN); } -int CheckaccessDescSignature(extended_hdr *exHdr, keys_struct *keys) +int CheckAccessDescSignature(access_descriptor *acexDesc, keys_struct *keys) { - u8 *AccessDesc = (u8*) &exHdr->accessDescriptor.ncchRsaPubKey; - u8 *Signature = (u8*) &exHdr->accessDescriptor.signature; + u8 *AccessDesc = (u8*) &acexDesc->ncchRsaPubKey; + u8 *Signature = (u8*) &acexDesc->signature; return ctr_sig(AccessDesc,0x300,Signature,keys->rsa.acexPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY); } @@ -74,21 +73,20 @@ int BuildExHeader(ncch_settings *ncchset) if(ncchset->options.IsCfa) return 0; - exheader_settings *exhdrset = malloc(sizeof(exheader_settings)); + exheader_settings *exhdrset = calloc(1,sizeof(exheader_settings)); if(!exhdrset) { fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); return MEM_ERROR; } - init_ExHeaderSettings(exhdrset); // Get Settings result = get_ExHeaderSettingsFromNcchset(exhdrset,ncchset); if(result) goto finish; - result = get_ExHeaderSettingsFromYaml(exhdrset); + result = get_ExHeaderSettingsFromRsf(exhdrset); if(result) goto finish; - result = set_AccessDesc(exhdrset,ncchset); + result = set_AccessDesc(exhdrset); if(result) goto finish; finish: @@ -97,12 +95,6 @@ finish: return result; } - -void init_ExHeaderSettings(exheader_settings *exhdrset) -{ - memset(exhdrset,0,sizeof(exheader_settings)); -} - void free_ExHeaderSettings(exheader_settings *exhdrset) { free(exhdrset); @@ -116,13 +108,19 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings * exhdrset->useAccessDescPreset = ncchset->keys->accessDescSign.presetType != desc_preset_NONE; /* Creating Output Buffer */ - ncchset->sections.exhdr.size = 0x800; - ncchset->sections.exhdr.buffer = malloc(ncchset->sections.exhdr.size); + ncchset->sections.exhdr.size = sizeof(extended_hdr); + ncchset->sections.exhdr.buffer = calloc(1,ncchset->sections.exhdr.size); if(!ncchset->sections.exhdr.buffer) { fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); return MEM_ERROR; } - memset(ncchset->sections.exhdr.buffer,0,ncchset->sections.exhdr.size); + + ncchset->sections.acexDesc.size = sizeof(access_descriptor); + ncchset->sections.acexDesc.buffer = calloc(1,ncchset->sections.acexDesc.size); + if(!ncchset->sections.acexDesc.buffer) { + fprintf(stderr,"[EXHEADER ERROR] Not enough memory\n"); + return MEM_ERROR; + } /* Import ExHeader Code Section template */ if(ncchset->componentFilePtrs.exhdrSize){ @@ -137,6 +135,7 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings * /* Create ExHeader Struct for output */ exhdrset->exHdr = (extended_hdr*)ncchset->sections.exhdr.buffer; + exhdrset->acexDesc = (access_descriptor*)ncchset->sections.acexDesc.buffer; /* Set Code Info if Code Section was built not imported */ if(ncchset->options.IsBuildingCodeSection){ @@ -167,7 +166,7 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings * return 0; } -int get_ExHeaderSettingsFromYaml(exheader_settings *exhdrset) +int get_ExHeaderSettingsFromRsf(exheader_settings *exhdrset) { int result = 0; result = get_ExHeaderCodeSetInfo(&exhdrset->exHdr->codeSetInfo, exhdrset->rsf); @@ -1171,22 +1170,14 @@ void exhdr_Print_ServiceAccessControl(extended_hdr *hdr) } /* ExHeader Binary Read Functions */ -u8* GetAccessDescSig_frm_exhdr(extended_hdr *hdr) +u8* GetAcexRsaSig(access_descriptor *acexDesc) { - if(!hdr) return NULL; - return hdr->accessDescriptor.signature ; + return acexDesc->signature ; } -u8* GetNcchHdrPubKey_frm_exhdr(extended_hdr *hdr) +u8* GetAcexNcchPubKey(access_descriptor *acexDesc) { - if(!hdr) return NULL; - return hdr->accessDescriptor.ncchRsaPubKey; -} - -u8* GetAccessDesc_frm_exhdr(extended_hdr *hdr) -{ - if(!hdr) return NULL; - return hdr->accessDescriptor.ncchRsaPubKey; + return acexDesc->ncchRsaPubKey; } u16 GetRemasterVersion_frm_exhdr(extended_hdr *hdr) diff --git a/makerom/exheader.h b/makerom/exheader.h index 431c776..82e778f 100644 --- a/makerom/exheader.h +++ b/makerom/exheader.h @@ -186,15 +186,17 @@ typedef struct exhdr_ARM11KernelCapabilities arm11KernelCapabilities; exhdr_ARM9AccessControlInfo arm9AccessControlInfo; // } - struct { - u8 signature[0x100]; - u8 ncchRsaPubKey[0x100]; - exhdr_ARM11SystemLocalCapabilities arm11SystemLocalCapabilities; - exhdr_ARM11KernelCapabilities arm11KernelCapabilities; - exhdr_ARM9AccessControlInfo arm9AccessControlInfo; - } accessDescriptor; } extended_hdr; +typedef struct +{ + u8 signature[0x100]; + u8 ncchRsaPubKey[0x100]; + exhdr_ARM11SystemLocalCapabilities arm11SystemLocalCapabilities; + exhdr_ARM11KernelCapabilities arm11KernelCapabilities; + exhdr_ARM9AccessControlInfo arm9AccessControlInfo; +} access_descriptor; + typedef struct { keys_struct *keys; @@ -203,12 +205,13 @@ typedef struct /* Output */ extended_hdr *exHdr; // is the exheader output buffer ptr(in ncchset) cast as exheader struct ptr; + access_descriptor *acexDesc; } exheader_settings; /* ExHeader Signature Functions */ -int SignAccessDesc(extended_hdr *ExHdr, keys_struct *keys); -int CheckaccessDescSignature(extended_hdr *ExHdr, keys_struct *keys); +int SignAccessDesc(access_descriptor *acexDesc, keys_struct *keys); +int CheckAccessDescSignature(access_descriptor *acexDesc, keys_struct *keys); /* ExHeader Build Functions */ int BuildExHeader(ncch_settings *ncchset); @@ -217,9 +220,8 @@ int BuildExHeader(ncch_settings *ncchset); void exhdr_Print_ServiceAccessControl(extended_hdr *hdr); /* ExHeader Binary Read Functions */ -u8* GetAccessDescSig_frm_exhdr(extended_hdr *hdr); -u8* GetNcchHdrPubKey_frm_exhdr(extended_hdr *hdr); -u8* GetAccessDesc_frm_exhdr(extended_hdr *hdr); +u8* GetAcexRsaSig(access_descriptor *acexDesc); +u8* GetAcexNcchPubKey(access_descriptor *acexDesc); u16 GetRemasterVersion_frm_exhdr(extended_hdr *hdr); u64 GetSaveDataSize_frm_exhdr(extended_hdr *hdr); int GetDependencyList_frm_exhdr(u8 *Dest,extended_hdr *hdr); diff --git a/makerom/keyset.c b/makerom/keyset.c index ce59b2d..38e5cf8 100644 --- a/makerom/keyset.c +++ b/makerom/keyset.c @@ -26,6 +26,7 @@ int SetTikCert(keys_struct *keys, u8 *Cert); int SetTmdCert(keys_struct *keys, u8 *Cert); int LoadKeysFromResources(keys_struct *keys); +void SetDummyRsaData(keys_struct *keys); int LoadKeysFromKeyfile(keys_struct *keys); void CheckAccessDescKey(keys_struct *keys); void DumpKeyset(keys_struct *keys); @@ -56,6 +57,9 @@ int SetKeys(keys_struct *keys) result = LoadKeysFromKeyfile(keys); if(result) return KEYSET_ERROR; } + + if(keys->rsa.isFalseSign) + SetDummyRsaData(keys); CheckAccessDescKey(keys); @@ -82,19 +86,7 @@ int LoadKeysFromResources(keys_struct *keys) //SetSystemFixedKey(keys,(u8*)zeros_aesKey); /* RSA Keys */ - keys->rsa.isFalseSign = true; - // CIA - SetTIK_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); - SetTMD_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); - // CCI/CFA - Set_CCI_CFA_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); - // CXI - SetAccessDesc_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); - - /* Certs */ - SetCaCert(keys,(u8*)ca3_tpki_cert); - SetTikCert(keys,(u8*)xsC_tpki_cert); - SetTmdCert(keys,(u8*)cpB_tpki_cert); + keys->rsa.isFalseSign = true; } #ifndef PUBLIC_BUILD else if(keys->keyset == pki_DEVELOPMENT){ @@ -166,11 +158,32 @@ int LoadKeysFromResources(keys_struct *keys) return 0; } +void SetDummyRsaData(keys_struct *keys) +{ + if(!keys->rsa.xsPvt || !keys->rsa.xsPub) + SetTIK_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); + if(!keys->rsa.cpPvt || !keys->rsa.cpPub) + SetTMD_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); + + if(!keys->rsa.cciCfaPvt || !keys->rsa.cciCfaPub) + Set_CCI_CFA_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); + + if(!keys->rsa.acexPvt || !keys->rsa.acexPub) + SetAccessDesc_RsaKey(keys,(u8*)tpki_rsa_privExp,(u8*)tpki_rsa_pubMod); + + /* Certs */ + if(!keys->certs.caCert) + SetCaCert(keys,(u8*)ca3_tpki_cert); + if(!keys->certs.xsCert) + SetTikCert(keys,(u8*)xsC_tpki_cert); + if(!keys->certs.cpCert) + SetTmdCert(keys,(u8*)cpB_tpki_cert); +} + int LoadKeysFromKeyfile(keys_struct *keys) { - //else - printf("[KEYSET ERROR] Target not supported\n"); - return 0; + printf("[KEYSET ERROR] Custom keys not supported\n"); + return -1; } void CheckAccessDescKey(keys_struct *keys) diff --git a/makerom/keyset.h b/makerom/keyset.h index 58291b0..81741a3 100644 --- a/makerom/keyset.h +++ b/makerom/keyset.h @@ -65,7 +65,7 @@ typedef struct { bool isFalseSign; // CIA RSA - u8 *cpPvt; //cpPvt + u8 *cpPvt; u8 *cpPub; u8 *xsPvt; u8 *xsPub; diff --git a/makerom/ncch.c b/makerom/ncch.c index 7eac1db..e8156db 100644 --- a/makerom/ncch.c +++ b/makerom/ncch.c @@ -366,20 +366,28 @@ int ImportLogo(ncch_settings *ncchset) int SetupNcch(ncch_settings *ncchset, romfs_buildctx *romfs) { u64 ncchSize = 0; - u64 exhdrSize,logoSize,plnRgnSize,exefsSize,romfsSize; - u64 exhdrOffset,logoOffset,plnRgnOffset,exefsOffset,romfsOffset; + u64 exhdrSize,acexSize,logoSize,plnRgnSize,exefsSize,romfsSize; + u64 exhdrOffset,acexOffset,logoOffset,plnRgnOffset,exefsOffset,romfsOffset; u32 exefsHashSize,romfsHashSize; ncchSize += 0x200; // Sig+Hdr // Sizes for NCCH hdr if(ncchset->sections.exhdr.size){ - exhdrSize = 0x400; + exhdrSize = ncchset->sections.exhdr.size; exhdrOffset = ncchSize; - ncchSize += ncchset->sections.exhdr.size; + ncchSize += exhdrSize; } else exhdrSize = 0; + + if(ncchset->sections.acexDesc.size){ + acexSize = ncchset->sections.acexDesc.size; + acexOffset = ncchSize; + ncchSize += acexSize; + } + else + acexSize = 0; if(ncchset->sections.logo.size){ logoSize = ncchset->sections.logo.size; @@ -443,6 +451,11 @@ int SetupNcch(ncch_settings *ncchset, romfs_buildctx *romfs) ncchset->sections.exhdr.buffer = NULL; u32_to_u8(hdr->exhdrSize,exhdrSize,LE); } + if(acexSize){ + memcpy((u8*)(ncch+acexOffset),ncchset->sections.acexDesc.buffer,ncchset->sections.acexDesc.size); + free(ncchset->sections.acexDesc.buffer); + ncchset->sections.acexDesc.buffer = NULL; + } if(logoSize){ memcpy((u8*)(ncch+logoOffset),ncchset->sections.logo.buffer,ncchset->sections.logo.size); @@ -496,13 +509,14 @@ int FinaliseNcch(ncch_settings *ncchset) ncch_hdr *hdr = (ncch_hdr*)(ncch + 0x100); u8 *exhdr = (u8*)(ncch + ncchset->cryptoDetails.exhdrOffset); + u8 *acexDesc = (u8*)(ncch + ncchset->cryptoDetails.acexOffset); u8 *logo = (u8*)(ncch + ncchset->cryptoDetails.logoOffset); u8 *exefs = (u8*)(ncch + ncchset->cryptoDetails.exefsOffset); u8 *romfs = (u8*)(ncch + ncchset->cryptoDetails.romfsOffset); // Taking Hashes\n"); if(ncchset->cryptoDetails.exhdrSize) - ctr_sha(exhdr,0x400,hdr->exhdrHash,CTR_SHA_256); + ctr_sha(exhdr,ncchset->cryptoDetails.exhdrSize,hdr->exhdrHash,CTR_SHA_256); if(ncchset->cryptoDetails.logoSize) ctr_sha(logo,ncchset->cryptoDetails.logoSize,hdr->logoHash,CTR_SHA_256); if(ncchset->cryptoDetails.exefsHashDataSize) @@ -527,10 +541,8 @@ int FinaliseNcch(ncch_settings *ncchset) SetNcchUnfixedKeys(ncchset->keys, ncch); // Getting AES Keys - u8 *key0 = GetNCCHKey(keyType, ncchset->keys); - u8 *key1 = GetNCCHKey(keyType, ncchset->keys); - if(keyType == KeyIsUnFixed2) - key0 = GetNCCHKey(KeyIsUnFixed, ncchset->keys); + u8 *key0 = GetNCCHKey0(keyType, ncchset->keys); + u8 *key1 = GetNCCHKey1(keyType, ncchset->keys); if(key0 == NULL || key1 == NULL){ fprintf(stderr,"[NCCH ERROR] Failed to load ncch aes key\n"); @@ -543,9 +555,11 @@ int FinaliseNcch(ncch_settings *ncchset) memdump(stdout,"key1: ",key1,16); */ - // Crypting Exheader - if(ncchset->cryptoDetails.exhdrSize) + // Crypting Exheader/AcexDesc + if(ncchset->cryptoDetails.exhdrSize){ CryptNCCHSection(exhdr,ncchset->cryptoDetails.exhdrSize,0x0,&ncchset->cryptoDetails,key0,ncch_exhdr); + CryptNCCHSection(acexDesc,ncchset->cryptoDetails.acexSize,ncchset->cryptoDetails.exhdrSize,&ncchset->cryptoDetails,key0,ncch_exhdr); + } // Crypting ExeFs Files if(ncchset->cryptoDetails.exefsSize){ @@ -618,12 +632,12 @@ int SetCommonHeaderBasicData(ncch_settings *ncchset, ncch_hdr *hdr) hdr->flags[OtherFlag] = (NoCrypto|FixedCryptoKey); else if(ncchset->keys->aes.ncchKeyX0){ hdr->flags[OtherFlag] = UnFixedCryptoKey; - if(ncchset->keys->aes.ncchKeyX1) + if(ncchset->keys->aes.ncchKeyX1 && !ncchset->options.IsCfa) hdr->flags[SecureCrypto2] = 1; } else{ hdr->flags[OtherFlag] = FixedCryptoKey; - u8 *key = GetNCCHKey(GetNCCHKeyType(hdr),ncchset->keys); + u8 *key = GetNCCHKey0(GetNCCHKeyType(hdr),ncchset->keys); if(!key){ // for detecting absense of fixed aes keys hdr->flags[OtherFlag] = (NoCrypto|FixedCryptoKey); fprintf(stderr,"[NCCH WARNING] NCCH AES Key could not be loaded, NCCH will not be encrypted\n"); @@ -702,15 +716,13 @@ int VerifyNCCH(u8 *ncch, keys_struct *keys, bool CheckHash, bool SuppressOutput) if(keyType != NoKey){ //memdump(stdout,"ncch: ",ncch,0x200); SetNcchUnfixedKeys(keys,ncch); - if(GetNCCHKey(keyType,keys) == NULL){ + if(GetNCCHKey0(keyType,keys) == NULL){ if(!SuppressOutput) fprintf(stderr,"[NCCH ERROR] Failed to load ncch aes key.\n"); return UNABLE_TO_LOAD_NCCH_KEY; } - key0 = GetNCCHKey(keyType,keys); - key1 = GetNCCHKey(keyType,keys); - if(keyType == KeyIsUnFixed2) - key0 = GetNCCHKey(KeyIsUnFixed,keys); + key0 = GetNCCHKey0(keyType,keys); + key1 = GetNCCHKey1(keyType,keys); } //memdump(stdout,"key0: ",key0,16); @@ -744,48 +756,60 @@ int VerifyNCCH(u8 *ncch, keys_struct *keys, bool CheckHash, bool SuppressOutput) free(ncch_ctx); return NO_EXEFS_IN_CXI; } - // Get ExHeader - extended_hdr *ExHeader = malloc(ncch_ctx->exhdrSize); - if(!ExHeader){ + // Get ExHeader/AcexDesc + extended_hdr *exHdr = malloc(ncch_ctx->exhdrSize); + if(!exHdr){ fprintf(stderr,"[NCCH ERROR] Not enough memory\n"); free(ncch_ctx); return MEM_ERROR; } - memcpy(ExHeader,ncch+ncch_ctx->exhdrOffset,ncch_ctx->exhdrSize); + memcpy(exHdr,ncch+ncch_ctx->exhdrOffset,ncch_ctx->exhdrSize); if(key0 != NULL) - CryptNCCHSection((u8*)ExHeader,ncch_ctx->exhdrSize,0,ncch_ctx,key0,ncch_exhdr); + CryptNCCHSection((u8*)exHdr,ncch_ctx->exhdrSize,0,ncch_ctx,key0,ncch_exhdr); // Checking Exheader Hash to see if decryption was sucessful - ctr_sha(ExHeader,0x400,Hash,CTR_SHA_256); + ctr_sha(exHdr,0x400,Hash,CTR_SHA_256); if(memcmp(Hash,hdr->exhdrHash,0x20) != 0){ //memdump(stdout,"Expected Hash: ",hdr->extended_header_sha_256_hash,0x20); //memdump(stdout,"Actual Hash: ",Hash,0x20); - //memdump(stdout,"Exheader: ",(u8*)ExHeader,0x400); + //memdump(stdout,"Exheader: ",(u8*)exHdr,0x400); if(!SuppressOutput) { fprintf(stderr,"[NCCH ERROR] ExHeader Hashcheck Failed\n"); fprintf(stderr,"[NCCH ERROR] CXI is corrupt\n"); } free(ncch_ctx); - free(ExHeader); + free(exHdr); return ExHeader_Hashfail; } - + free(exHdr); + // Checking RSA Sigs - u8 *hdr_pubk = GetNcchHdrPubKey_frm_exhdr(ExHeader); + access_descriptor *acexDesc = malloc(ncch_ctx->acexSize); + if(!acexDesc){ + fprintf(stderr,"[NCCH ERROR] Not enough memory\n"); + free(ncch_ctx); + free(exHdr); + return MEM_ERROR; + } + memcpy(acexDesc,ncch+ncch_ctx->acexOffset,ncch_ctx->acexSize); + if(key0 != NULL) + CryptNCCHSection((u8*)acexDesc,ncch_ctx->acexSize,ncch_ctx->exhdrOffset,ncch_ctx,key0,ncch_exhdr); - if(CheckaccessDescSignature(ExHeader,keys) != 0 && !keys->rsa.isFalseSign){ + if(CheckAccessDescSignature(acexDesc,keys) != 0 && !keys->rsa.isFalseSign){ if(!SuppressOutput) fprintf(stderr,"[NCCH ERROR] AccessDesc Sigcheck Failed\n"); free(ncch_ctx); - free(ExHeader); + free(acexDesc); return ACCESSDESC_SIG_BAD; } - if(CheckCXISignature(hdr_sig,(u8*)hdr,hdr_pubk) != 0 /* && !keys->rsa.isFalseSign*/){ // This should always be correct + + u8 *hdr_pubk = GetAcexNcchPubKey(acexDesc); + + if(CheckCXISignature(hdr_sig,(u8*)hdr,hdr_pubk) != 0 && !keys->rsa.isFalseSign){ if(!SuppressOutput) fprintf(stderr,"[NCCH ERROR] CXI Header Sigcheck Failed\n"); - free(ncch_ctx); - free(ExHeader); + free(ncch_ctx); + free(acexDesc); return NCCH_HDR_SIG_BAD; } - free(ExHeader); } if(!CheckHash) @@ -904,7 +928,7 @@ int ModifyNcchIds(u8 *ncch, u8 *titleId, u8 *programId, keys_struct *keys) GetNCCHStruct(&ncch_struct,hdr); romfs = (ncch+ncch_struct.romfsOffset); SetNcchUnfixedKeys(keys, ncch); // For Secure Crypto - key = GetNCCHKey(keytype,keys); + key = GetNCCHKey1(keytype,keys); if(key == NULL){ fprintf(stderr,"[NCCH ERROR] Failed to load ncch aes key\n"); //free(ncch); @@ -928,7 +952,7 @@ int ModifyNcchIds(u8 *ncch, u8 *titleId, u8 *programId, keys_struct *keys) GetNCCHStruct(&ncch_struct,hdr); romfs = (ncch+ncch_struct.romfsOffset); SetNcchUnfixedKeys(keys, ncch); // For Secure Crypto - key = GetNCCHKey(keytype,keys); + key = GetNCCHKey1(keytype,keys); if(key == NULL){ fprintf(stderr,"[NCCH ERROR] Failed to load ncch aes key\n"); //free(ncch); @@ -1013,7 +1037,25 @@ ncch_key_type GetNCCHKeyType(ncch_hdr* hdr) return KeyIsUnFixed; } -u8* GetNCCHKey(ncch_key_type keytype, keys_struct *keys) +u8* GetNCCHKey0(ncch_key_type keytype, keys_struct *keys) +{ + switch(keytype){ + case NoKey: return NULL; + case KeyIsNormalFixed: + return keys->aes.normalKey; + case KeyIsSystemFixed: + return keys->aes.systemFixedKey; + case KeyIsUnFixed: + case KeyIsUnFixed2: + if(keys->aes.ncchKeyX0) + return keys->aes.unFixedKey0; + else + return NULL; + } + return NULL; +} + +u8* GetNCCHKey1(ncch_key_type keytype, keys_struct *keys) { switch(keytype){ case NoKey: return NULL; @@ -1035,65 +1077,6 @@ u8* GetNCCHKey(ncch_key_type keytype, keys_struct *keys) return NULL; } -int GetNCCHSection(u8 *dest, u64 dest_max_size, u64 src_pos, u8 *ncch, ncch_struct *ncch_ctx, keys_struct *keys, ncch_section section) -{ - if(!ncch) return MEM_ERROR; - u8 *key = NULL; - ncch_hdr* hdr = GetNCCH_CommonHDR(NULL,NULL,ncch); - ncch_key_type keytype = GetNCCHKeyType(hdr); - - if(keytype != NoKey && (section == ncch_exhdr || section == ncch_exefs || section == ncch_romfs)){ - key = GetNCCHKey(keytype,keys); - if(key == NULL){ - //fprintf(stderr,"[NCCH ERROR] Failed to load ncch aes key.\n"); - return UNABLE_TO_LOAD_NCCH_KEY; - } - } - //printf("detecting section type\n"); - u64 offset = 0; - u64 size = 0; - switch(section){ - case ncch_exhdr: - offset = ncch_ctx->exhdrOffset; - size = ncch_ctx->exhdrSize; - break; - case ncch_Logo: - offset = ncch_ctx->logoOffset; - size = ncch_ctx->logoSize; - break; - case ncch_PlainRegion: - offset = ncch_ctx->plainRegionOffset; - size = ncch_ctx->plainRegionSize; - break; - case ncch_exefs: - offset = ncch_ctx->exefsOffset; - size = ncch_ctx->exefsSize; - break; - case ncch_romfs: - offset = ncch_ctx->romfsOffset; - size = ncch_ctx->romfsSize; - break; - } - if(!offset || !size) return NCCH_SECTION_NOT_EXIST; - - if(src_pos > size) return DATA_POS_DNE; - - size = min_u64(size-src_pos,dest_max_size); - - //printf("Copying data\n"); - u8 *section_pos = (ncch + offset + src_pos); - memcpy(dest,section_pos,size); - - //printf("decrypting if needed\n"); - if(keytype != NoKey && (section == ncch_exhdr || section == ncch_exefs || section == ncch_romfs)){ // Decrypt - //memdump(stdout,"Key: ",key,16); - CryptNCCHSection(dest,size,src_pos,ncch_ctx,key,section); - //printf("no cigar\n"); - } - //printf("Got thing okay\n"); - return 0; -} - int GetNCCHStruct(ncch_struct *ctx, ncch_hdr *header) { memcpy(ctx->titleId,header->titleId,8); @@ -1105,7 +1088,9 @@ int GetNCCHStruct(ncch_struct *ctx, ncch_hdr *header) ctx->formatVersion = u8_to_u16(header->formatVersion,LE); if(!IsCfa(header)){ ctx->exhdrOffset = 0x200; - ctx->exhdrSize = u8_to_u32(header->exhdrSize,LE) + 0x400; + ctx->exhdrSize = u8_to_u32(header->exhdrSize,LE); + ctx->acexOffset = (ctx->exhdrOffset + ctx->exhdrSize); + ctx->acexSize = sizeof(access_descriptor); ctx->plainRegionOffset = (u64)(u8_to_u32(header->plainRegionOffset,LE)*media_unit); ctx->plainRegionSize = (u64)(u8_to_u32(header->plainRegionSize,LE)*media_unit); } diff --git a/makerom/ncch.h b/makerom/ncch.h index 1baef1f..232a228 100644 --- a/makerom/ncch.h +++ b/makerom/ncch.h @@ -74,6 +74,8 @@ typedef struct u16 formatVersion; u32 exhdrOffset; u32 exhdrSize; + u32 acexOffset; + u32 acexSize; u64 logoOffset; u64 logoSize; u64 plainRegionOffset; @@ -126,7 +128,6 @@ typedef struct buffer_struct *out; keys_struct *keys; rsf_settings *rsfSet; - struct { @@ -192,6 +193,7 @@ typedef struct struct { buffer_struct exhdr; + buffer_struct acexDesc; buffer_struct logo; buffer_struct plainRegion; buffer_struct exeFs; @@ -220,8 +222,8 @@ u32 GetNCCH_MediaUnitSize(ncch_hdr* hdr); u32 GetNCCH_MediaSize(ncch_hdr* hdr); ncch_key_type GetNCCHKeyType(ncch_hdr* hdr); -int GetNCCHSection(u8 *dest, u64 dest_max_size, u64 src_pos, u8 *ncch, ncch_struct *ncch_ctx, keys_struct *keys, ncch_section section); -u8* GetNCCHKey(ncch_key_type keytype, keys_struct *keys); +u8* GetNCCHKey0(ncch_key_type keytype, keys_struct *keys); +u8* GetNCCHKey1(ncch_key_type keytype, keys_struct *keys); int GetNCCHStruct(ncch_struct *ctx, ncch_hdr *header); void ncch_get_counter(ncch_struct *ctx, u8 counter[16], u8 type);