mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
Fixed some errors and bad programming
This commit is contained in:
+77
-76
@@ -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,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int set_AccessDesc(exheader_settings *exhdrset, ncch_settings *ncchset);
|
||||
int set_AccessDesc(exheader_settings *exhdrset);
|
||||
+10
-17
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -65,7 +65,7 @@ typedef struct
|
||||
{
|
||||
bool isFalseSign;
|
||||
// CIA RSA
|
||||
u8 *cpPvt; //cpPvt
|
||||
u8 *cpPvt;
|
||||
u8 *cpPub;
|
||||
u8 *xsPvt;
|
||||
u8 *xsPub;
|
||||
|
||||
+82
-97
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user