Files
Project_CTR/makerom/accessdesc.c
T
2015-12-23 14:49:19 +08:00

209 lines
8.2 KiB
C

#include "lib.h"
#include "ncch_build.h"
#include "exheader_build.h"
#include "accessdesc.h"
#include "desc/presets.h"
#include "desc/dev_sigdata.h"
const int RSF_RSA_DATA_LEN = 344;
const int RSF_DESC_DATA_LEN = 684;
int accessdesc_SignWithKey(exheader_settings *exhdrset);
int accessdesc_GetSignFromRsf(exheader_settings *exhdrset);
int accessdesc_GetSignFromPreset(exheader_settings *exhdrset);
const CtrSdkDesc* accessdesc_GetPresetData(keys_struct *keys);
const CtrSdkDescSignData* accessdesc_GetPresetSignData(keys_struct *keys);
const CtrSdkDepList* accessdesc_GetPresetDependencyList(keys_struct *keys);
int set_AccessDesc(exheader_settings *exhdrset)
{
if(exhdrset->useAccessDescPreset) // Use AccessDesc Template
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,"[ACEXDESC ERROR] Current keyset cannot sign AccessDesc, please appropriately set-up RSF, or specify a preset with \"-desc\"\n");
return CANNOT_SIGN_ACCESSDESC;
}
}
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->acexDesc->ncchRsaPubKey,exhdrset->keys->rsa.cxiHdrPub,0x100);
/* Copy Data From ExHeader */
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 */
exhdr_ARM11SystemLocalCapabilities *arm11 = &exhdrset->acexDesc->arm11SystemLocalCapabilities;
arm11->idealProcessor = 1 << arm11->idealProcessor;
arm11->threadPriority /= 2;
/* Sign AccessDesc */
return SignAccessDesc(exhdrset->acexDesc,exhdrset->keys);
}
int accessdesc_GetSignFromRsf(exheader_settings *exhdrset)
{
/* Yaml Option Sanity Checks */
if(!exhdrset->rsf->CommonHeaderKey.Found){
fprintf(stderr,"[ACEXDESC ERROR] RSF Section \"CommonHeaderKey\" not found\n");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->rsf->CommonHeaderKey.D){
ErrorParamNotFound("CommonHeaderKey/D");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.D) != RSF_RSA_DATA_LEN){
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/D\" has invalid length (%d)\n",b64_strlen(exhdrset->rsf->CommonHeaderKey.D));
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->rsf->CommonHeaderKey.Modulus){
ErrorParamNotFound("CommonHeaderKey/Modulus");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.Modulus) != RSF_RSA_DATA_LEN){
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/Modulus\" has invalid length (%d)\n",b64_strlen(exhdrset->rsf->CommonHeaderKey.Modulus));
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->rsf->CommonHeaderKey.AccCtlDescSign){
ErrorParamNotFound("CommonHeaderKey/Signature");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescSign) != RSF_RSA_DATA_LEN){
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/Signature\" has invalid length (%d)\n",b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescSign));
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->rsf->CommonHeaderKey.AccCtlDescBin){
ErrorParamNotFound("CommonHeaderKey/Descriptor");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescBin) != RSF_DESC_DATA_LEN){
fprintf(stderr,"[ACEXDESC ERROR] \"CommonHeaderKey/Descriptor\" has invalid length (%d)\n",b64_strlen(exhdrset->rsf->CommonHeaderKey.AccCtlDescBin));
return COMMON_HEADER_KEY_NOT_FOUND;
}
/* Set RSA Keys */
int result = 0;
// NCCH Header pubk
result = b64_decode(exhdrset->keys->rsa.cxiHdrPub,exhdrset->rsf->CommonHeaderKey.Modulus,0x100);
if(result) return result;
// NCCH Header privk
result = b64_decode(exhdrset->keys->rsa.cxiHdrPvt,exhdrset->rsf->CommonHeaderKey.D,0x100);
if(result) return result;
/* Set AccessDesc */
// Signature
result = b64_decode(exhdrset->acexDesc->signature,exhdrset->rsf->CommonHeaderKey.AccCtlDescSign,0x100);
if(result) return result;
// NCCH Header pubk
memcpy(exhdrset->acexDesc->ncchRsaPubKey,exhdrset->keys->rsa.cxiHdrPub,0x100);
// Access Control
result = b64_decode((u8*)&exhdrset->acexDesc->arm11SystemLocalCapabilities,exhdrset->rsf->CommonHeaderKey.AccCtlDescBin,0x200);
if(result) return result;
return 0;
}
int accessdesc_GetSignFromPreset(exheader_settings *exhdrset)
{
const CtrSdkDesc *desc = accessdesc_GetPresetData(exhdrset->keys);
const CtrSdkDescSignData *pre_sign = accessdesc_GetPresetSignData(exhdrset->keys);
const CtrSdkDepList *dependency_list = accessdesc_GetPresetDependencyList(exhdrset->keys);
// Error Checking
if(!desc || !dependency_list){
fprintf(stderr,"[ACEXDESC ERROR] AccessDesc template is unavailable, please configure RSF file\n");
return CANNOT_SIGN_ACCESSDESC;
}
if(!pre_sign->modulus && exhdrset->keys->rsa.requiresPresignedDesc){
fprintf(stderr,"[ACEXDESC ERROR] This AccessDesc template 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, dependency_list->dependency, 0x180);
// Backing Up Non Preset Data
u8 ProgramID[8];
exhdr_StorageInfo StorageInfoBackup;
exhdr_ARM9AccessControlInfo Arm9Desc;
memcpy(ProgramID, exhdrset->exHdr->arm11SystemLocalCapabilities.programId, 8);
memcpy(&StorageInfoBackup, &exhdrset->exHdr->arm11SystemLocalCapabilities.storageInfo, sizeof(exhdr_StorageInfo));
memcpy(&Arm9Desc, &exhdrset->exHdr->arm9AccessControlInfo, sizeof(exhdr_ARM9AccessControlInfo));
// Setting Preset Data
memcpy(&exhdrset->exHdr->arm11SystemLocalCapabilities, desc->exheader_desc, 0x200);
// Restoring Non Preset Data
memcpy(exhdrset->exHdr->arm11SystemLocalCapabilities.programId, ProgramID, 8);
memcpy(&exhdrset->exHdr->arm11SystemLocalCapabilities.storageInfo, &StorageInfoBackup, sizeof(exhdr_StorageInfo));
memcpy(&exhdrset->exHdr->arm9AccessControlInfo, &Arm9Desc, sizeof(exhdr_ARM9AccessControlInfo));
// Setting AccessDesc Area
// Signing normally if possible
if(!exhdrset->keys->rsa.requiresPresignedDesc)
return accessdesc_SignWithKey(exhdrset);
// Otherwise set static data & ncch hdr sig info
memcpy(exhdrset->keys->rsa.cxiHdrPub, pre_sign->modulus, 0x100);
memcpy(exhdrset->keys->rsa.cxiHdrPvt, pre_sign->priv_exponent, 0x100);
memcpy(&exhdrset->acexDesc->signature, pre_sign->access_desc_signature, 0x100);
memcpy(&exhdrset->acexDesc->ncchRsaPubKey, pre_sign->modulus, 0x100);
memcpy(&exhdrset->acexDesc->arm11SystemLocalCapabilities, desc->signed_desc, 0x200);
return 0;
}
const CtrSdkDesc* accessdesc_GetPresetData(keys_struct *keys)
{
for (int i = 0; i < sizeof(kDescPresets) / sizeof(CtrSdkDesc); i++) {
if (kDescPresets[i].type == keys->accessDescSign.presetType && kDescPresets[i].fw_minor == keys->accessDescSign.targetFirmware) {
return &kDescPresets[i];
}
}
return NULL;
}
const CtrSdkDescSignData* accessdesc_GetPresetSignData(keys_struct *keys)
{
if (keys->keyset != pki_DEVELOPMENT) {
return NULL;
}
for (int i = 0; i < sizeof(kDevDescSignData) / sizeof(CtrSdkDescSignData); i++) {
if (kDevDescSignData[i].type == keys->accessDescSign.presetType && kDevDescSignData[i].fw_minor == keys->accessDescSign.targetFirmware) {
return &kDevDescSignData[i];
}
}
return NULL;
}
const CtrSdkDepList* accessdesc_GetPresetDependencyList(keys_struct *keys)
{
for (int i = 0; i < sizeof(kExheaderDependencyLists) / sizeof(CtrSdkDepList); i++) {
if (kExheaderDependencyLists[i].fw_minor == keys->accessDescSign.targetFirmware) {
return &kExheaderDependencyLists[i];
}
}
return NULL;
}