Fixed some errors and bad programming

This commit is contained in:
applestash
2014-06-21 18:21:22 +10:00
parent 5ffe17390c
commit dc8de388a3
11 changed files with 246 additions and 259 deletions
+77 -76
View File
@@ -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);
}
+1 -1
View File
@@ -1,3 +1,3 @@
#pragma once
int set_AccessDesc(exheader_settings *exhdrset, ncch_settings *ncchset);
int set_AccessDesc(exheader_settings *exhdrset);
+10 -17
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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]);
}
}
+25 -34
View File
@@ -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)
+14 -12
View File
@@ -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);
+29 -16
View File
@@ -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)
+1 -1
View File
@@ -65,7 +65,7 @@ typedef struct
{
bool isFalseSign;
// CIA RSA
u8 *cpPvt; //cpPvt
u8 *cpPvt;
u8 *cpPub;
u8 *xsPvt;
u8 *xsPub;
+82 -97
View File
@@ -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);
}
+5 -3
View File
@@ -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);