mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
[makerom] Relaxed support for bad signatures (-ignoresign). Warns user when something cannot be signed, instead of treating it like a fatal error.
This commit is contained in:
+36
-32
@@ -19,29 +19,27 @@ const CtrSdkDepList* accessdesc_GetPresetDependencyList(keys_struct *keys);
|
||||
|
||||
int set_AccessDesc(exheader_settings *exhdrset)
|
||||
{
|
||||
if(exhdrset->useAccessDescPreset) // Use AccessDesc Template
|
||||
if(exhdrset->useAccessDescPreset == true) // Use AccessDesc Template
|
||||
return accessdesc_GetSignFromPreset(exhdrset);
|
||||
else if(exhdrset->rsf->CommonHeaderKey.Found) // Keydata exists in RSF
|
||||
else if(exhdrset->rsf->CommonHeaderKey.Found == true) // Keydata exists in RSF
|
||||
return accessdesc_GetSignFromRsf(exhdrset);
|
||||
else if(!exhdrset->keys->rsa.requiresPresignedDesc) // Else if The AccessDesc can be signed with key
|
||||
else if (Rsa2048Key_CanSign(&exhdrset->keys->rsa.acex) == false) // sign using rsa 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;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
memcpy(exhdrset->keys->rsa.cxi.pvt, exhdrset->keys->rsa.cciCfa.pvt, 0x100);
|
||||
memcpy(exhdrset->keys->rsa.cxi.pub, exhdrset->keys->rsa.cciCfa.pub, 0x100);
|
||||
memcpy(&exhdrset->acexDesc->ncchRsaPubKey, exhdrset->keys->rsa.cxi.pub, 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));
|
||||
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;
|
||||
@@ -50,7 +48,13 @@ int accessdesc_SignWithKey(exheader_settings *exhdrset)
|
||||
arm11->threadPriority /= 2;
|
||||
|
||||
/* Sign AccessDesc */
|
||||
return SignAccessDesc(exhdrset->acexDesc,exhdrset->keys);
|
||||
if (SignAccessDesc(exhdrset->acexDesc, exhdrset->keys) != 0)
|
||||
{
|
||||
printf("[ACEXDESC WARNING] Failed to sign access descriptor\n");
|
||||
memset(exhdrset->acexDesc->signature, 0xFF, 0x100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int accessdesc_GetSignFromRsf(exheader_settings *exhdrset)
|
||||
@@ -100,10 +104,10 @@ int accessdesc_GetSignFromRsf(exheader_settings *exhdrset)
|
||||
/* Set RSA Keys */
|
||||
int result = 0;
|
||||
// NCCH Header pubk
|
||||
result = b64_decode(exhdrset->keys->rsa.cxiHdrPub,exhdrset->rsf->CommonHeaderKey.Modulus,0x100);
|
||||
result = b64_decode(exhdrset->keys->rsa.cxi.pub,exhdrset->rsf->CommonHeaderKey.Modulus,0x100);
|
||||
if(result) return result;
|
||||
// NCCH Header privk
|
||||
result = b64_decode(exhdrset->keys->rsa.cxiHdrPvt,exhdrset->rsf->CommonHeaderKey.D,0x100);
|
||||
result = b64_decode(exhdrset->keys->rsa.cxi.pvt,exhdrset->rsf->CommonHeaderKey.D,0x100);
|
||||
if(result) return result;
|
||||
|
||||
/* Set AccessDesc */
|
||||
@@ -111,7 +115,7 @@ int accessdesc_GetSignFromRsf(exheader_settings *exhdrset)
|
||||
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);
|
||||
memcpy(exhdrset->acexDesc->ncchRsaPubKey,exhdrset->keys->rsa.cxi.pub,0x100);
|
||||
// Access Control
|
||||
result = b64_decode((u8*)&exhdrset->acexDesc->arm11SystemLocalCapabilities,exhdrset->rsf->CommonHeaderKey.AccCtlDescBin,0x200);
|
||||
if(result) return result;
|
||||
@@ -127,13 +131,8 @@ int accessdesc_GetSignFromPreset(exheader_settings *exhdrset)
|
||||
|
||||
|
||||
// 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 && 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");
|
||||
if (!desc || !dependency_list) {
|
||||
fprintf(stderr, "[ACEXDESC ERROR] AccessDesc template is unavailable, please configure RSF file\n");
|
||||
return CANNOT_SIGN_ACCESSDESC;
|
||||
}
|
||||
|
||||
@@ -159,16 +158,21 @@ int accessdesc_GetSignFromPreset(exheader_settings *exhdrset)
|
||||
|
||||
|
||||
// Setting AccessDesc Area
|
||||
// Signing normally if possible
|
||||
if(!exhdrset->keys->rsa.requiresPresignedDesc)
|
||||
// If presign available set static data & ncch hdr sig info
|
||||
if (pre_sign)
|
||||
{
|
||||
memcpy(exhdrset->keys->rsa.cxi.pub, pre_sign->modulus, 0x100);
|
||||
memcpy(exhdrset->keys->rsa.cxi.pvt, 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);
|
||||
}
|
||||
// otherwise sign properly
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -58,14 +58,14 @@ int SignAccessDesc(access_descriptor *acexDesc, keys_struct *keys)
|
||||
{
|
||||
u8 *data = (u8*) &acexDesc->ncchRsaPubKey;
|
||||
u8 *sign = (u8*) &acexDesc->signature;
|
||||
return RsaSignVerify(data,0x300,sign,keys->rsa.acexPub,keys->rsa.acexPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
|
||||
return RsaSignVerify(data, 0x300, sign, keys->rsa.acex.pub, keys->rsa.acex.pvt, RSA_2048_SHA256, CTR_RSA_SIGN);
|
||||
}
|
||||
|
||||
int CheckAccessDescSignature(access_descriptor *acexDesc, keys_struct *keys)
|
||||
{
|
||||
u8 *data = (u8*) &acexDesc->ncchRsaPubKey;
|
||||
u8 *sign = (u8*) &acexDesc->signature;
|
||||
return RsaSignVerify(data,0x300,sign,keys->rsa.acexPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
|
||||
return RsaSignVerify(data,0x300,sign,keys->rsa.acex.pub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
|
||||
}
|
||||
|
||||
/* ExHeader Build Functions */
|
||||
|
||||
+80
-105
@@ -15,12 +15,6 @@ int SetNcchKeyX(keys_struct *keys, const u8 *keyX, u8 index);
|
||||
void keysetOpenError(char *file);
|
||||
FILE* keyset_OpenFile(char *dir, char *name, bool FileRequired);
|
||||
|
||||
int SetTIK_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus);
|
||||
int SetTMD_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus);
|
||||
int Set_CCI_CFA_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus);
|
||||
int SetAccessDesc_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus);
|
||||
int SetCXI_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus);
|
||||
|
||||
int SetCaCert(keys_struct *keys, const u8 *cert);
|
||||
int SetTikCert(keys_struct *keys, const u8 *cert);
|
||||
int SetTmdCert(keys_struct *keys, const u8 *cert);
|
||||
@@ -28,17 +22,21 @@ int SetTmdCert(keys_struct *keys, const 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);
|
||||
|
||||
|
||||
|
||||
// Code
|
||||
void InitKeys(keys_struct *keys)
|
||||
{
|
||||
memset(keys,0,sizeof(keys_struct));
|
||||
InitCommonKeySlots(keys);
|
||||
InitNcchKeyXSlots(keys);
|
||||
keys->rsa.cxiHdrPub = malloc(RSA_2048_KEY_SIZE);
|
||||
keys->rsa.cxiHdrPvt = malloc(RSA_2048_KEY_SIZE);
|
||||
Rsa2048Key_Alloc(&keys->rsa.xs);
|
||||
Rsa2048Key_Alloc(&keys->rsa.cp);
|
||||
Rsa2048Key_Alloc(&keys->rsa.cciCfa);
|
||||
Rsa2048Key_Alloc(&keys->rsa.acex);
|
||||
Rsa2048Key_Alloc(&keys->rsa.cxi);
|
||||
keys->aes.ncchKey0 = malloc(AES_128_KEY_SIZE);
|
||||
keys->aes.ncchKey1 = malloc(AES_128_KEY_SIZE);
|
||||
}
|
||||
@@ -50,22 +48,20 @@ void PrintBadKeySize(char *path, u32 size)
|
||||
|
||||
int SetKeys(keys_struct *keys)
|
||||
{
|
||||
int result = 0;
|
||||
result = LoadKeysFromResources(keys);
|
||||
if(result) return KEYSET_ERROR;
|
||||
|
||||
if(!keys->keysetLoaded){
|
||||
result = LoadKeysFromKeyfile(keys);
|
||||
if(result) return KEYSET_ERROR;
|
||||
if (LoadKeysFromResources(keys) != 0)
|
||||
{
|
||||
return KEYSET_ERROR;
|
||||
}
|
||||
|
||||
if(keys->rsa.isFalseSign)
|
||||
SetDummyRsaData(keys);
|
||||
if (!keys->keysetLoaded)
|
||||
{
|
||||
return KEYSET_ERROR;
|
||||
}
|
||||
|
||||
CheckAccessDescKey(keys);
|
||||
|
||||
if(keys->dumpkeys)
|
||||
if (keys->dumpkeys)
|
||||
{
|
||||
DumpKeyset(keys);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -84,8 +80,10 @@ int LoadKeysFromResources(keys_struct *keys)
|
||||
SetNormalKey(keys,zeros_aesKey);
|
||||
SetSystemFixedKey(keys,zeros_aesKey);
|
||||
|
||||
/* RSA Keys */
|
||||
keys->rsa.isFalseSign = true;
|
||||
/* Certs */
|
||||
SetCaCert(keys, ca3_tpki_cert);
|
||||
SetTikCert(keys, xsC_tpki_cert);
|
||||
SetTmdCert(keys, cpB_tpki_cert);
|
||||
}
|
||||
else if(keys->keyset == pki_DEVELOPMENT){
|
||||
keys->keysetLoaded = true;
|
||||
@@ -105,15 +103,14 @@ int LoadKeysFromResources(keys_struct *keys)
|
||||
for(int i = 0; i < 4; i++)
|
||||
SetNcchKeyX(keys, dev_unfixed_ncch_keyX[i],i);
|
||||
|
||||
|
||||
/* RSA Keys */
|
||||
// CIA
|
||||
SetTIK_RsaKey(keys, xs9_dpki_rsa.priv_exponent, xs9_dpki_rsa.modulus);
|
||||
SetTMD_RsaKey(keys, cpA_dpki_rsa.priv_exponent, cpA_dpki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.xs, xs9_dpki_rsa.priv_exponent, xs9_dpki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cp, cpA_dpki_rsa.priv_exponent, cpA_dpki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
Set_CCI_CFA_RsaKey(keys, dev_ncsd_cfa_rsa.priv_exponent, dev_ncsd_cfa_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, dev_ncsd_cfa_rsa.priv_exponent, dev_ncsd_cfa_rsa.modulus);
|
||||
// CXI
|
||||
SetAccessDesc_RsaKey(keys, dev_accessdesc_rsa.priv_exponent, dev_accessdesc_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.acex, dev_accessdesc_rsa.priv_exponent, dev_accessdesc_rsa.modulus);
|
||||
|
||||
/* Certs */
|
||||
SetCaCert(keys, ca4_dpki_cert);
|
||||
@@ -140,12 +137,12 @@ int LoadKeysFromResources(keys_struct *keys)
|
||||
|
||||
/* RSA Keys */
|
||||
// CIA
|
||||
SetTIK_RsaKey(keys, xsC_ppki_rsa.priv_exponent, xsC_ppki_rsa.modulus);
|
||||
SetTMD_RsaKey(keys, cpB_ppki_rsa.priv_exponent, cpB_ppki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.xs, xsC_ppki_rsa.priv_exponent, xsC_ppki_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cp, cpB_ppki_rsa.priv_exponent, cpB_ppki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
Set_CCI_CFA_RsaKey(keys, prod_ncsd_cfa_rsa.priv_exponent, prod_ncsd_cfa_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, prod_ncsd_cfa_rsa.priv_exponent, prod_ncsd_cfa_rsa.modulus);
|
||||
// CXI
|
||||
SetAccessDesc_RsaKey(keys, prod_accessdesc_rsa.priv_exponent, prod_accessdesc_rsa.modulus);
|
||||
Rsa2048Key_Set(&keys->rsa.acex, prod_accessdesc_rsa.priv_exponent, prod_accessdesc_rsa.modulus);
|
||||
|
||||
/* Certs */
|
||||
SetCaCert(keys, ca3_ppki_cert);
|
||||
@@ -155,20 +152,22 @@ int LoadKeysFromResources(keys_struct *keys)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
void SetDummyRsaData(keys_struct *keys)
|
||||
{
|
||||
if(!keys->rsa.xsPvt || !keys->rsa.xsPub)
|
||||
SetTIK_RsaKey(keys, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
if(!keys->rsa.cpPvt || !keys->rsa.cpPub)
|
||||
SetTMD_RsaKey(keys, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CIA
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.xs) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.xs, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.cp) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.cp, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CCI/CFA
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.cciCfa) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.cciCfa, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
// CXI
|
||||
if (Rsa2048Key_CanSign(&keys->rsa.acex) == false)
|
||||
Rsa2048Key_Set(&keys->rsa.acex, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
|
||||
if(!keys->rsa.cciCfaPvt || !keys->rsa.cciCfaPub)
|
||||
Set_CCI_CFA_RsaKey(keys, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
|
||||
if(!keys->rsa.acexPvt || !keys->rsa.acexPub)
|
||||
SetAccessDesc_RsaKey(keys, tpki_rsa.priv_exponent, tpki_rsa.modulus);
|
||||
|
||||
/* Certs */
|
||||
// Certs
|
||||
if(!keys->certs.caCert)
|
||||
SetCaCert(keys, ca3_tpki_cert);
|
||||
if(!keys->certs.xsCert)
|
||||
@@ -176,24 +175,7 @@ void SetDummyRsaData(keys_struct *keys)
|
||||
if(!keys->certs.cpCert)
|
||||
SetTmdCert(keys, cpB_tpki_cert);
|
||||
}
|
||||
|
||||
int LoadKeysFromKeyfile(keys_struct *keys)
|
||||
{
|
||||
printf("[KEYSET ERROR] Custom keys not supported\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CheckAccessDescKey(keys_struct *keys)
|
||||
{
|
||||
// Checking if AccessDesc can be signed
|
||||
u8 *tmp = calloc(1,RSA_2048_KEY_SIZE);
|
||||
if(memcmp(tmp,keys->rsa.acexPvt,RSA_2048_KEY_SIZE) == 0)
|
||||
keys->rsa.requiresPresignedDesc = true;
|
||||
else
|
||||
keys->rsa.requiresPresignedDesc = false;
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
*/
|
||||
|
||||
void DumpKeyset(keys_struct *keys)
|
||||
{
|
||||
@@ -245,17 +227,17 @@ void DumpKeyset(keys_struct *keys)
|
||||
}
|
||||
|
||||
printf(" > TIK RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.xsPub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.xsPvt,0x100);
|
||||
memdump(stdout," [PUB] ",keys->rsa.xs.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.xs.pvt,0x100);
|
||||
printf(" > TMD RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.cpPub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.cpPvt,0x100);
|
||||
memdump(stdout," [PUB] ",keys->rsa.cp.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.cp.pvt,0x100);
|
||||
printf(" > AcexDesc RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.acexPub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.acexPvt,0x100);
|
||||
memdump(stdout," [PUB] ",keys->rsa.acex.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.acex.pvt,0x100);
|
||||
printf(" > NcsdCfa RSA Keys\n");
|
||||
memdump(stdout," [PUB] ",keys->rsa.cciCfaPub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.cciCfaPvt,0x100);
|
||||
memdump(stdout," [PUB] ",keys->rsa.cciCfa.pub,0x100);
|
||||
memdump(stdout," [PVT] ",keys->rsa.cciCfa.pvt,0x100);
|
||||
}
|
||||
|
||||
void keysetOpenError(char *file)
|
||||
@@ -301,18 +283,11 @@ void FreeKeys(keys_struct *keys)
|
||||
free(keys->aes.ncchKey1);
|
||||
|
||||
// RSA
|
||||
free(keys->rsa.xsPvt);
|
||||
free(keys->rsa.xsPub);
|
||||
free(keys->rsa.cpPvt);
|
||||
free(keys->rsa.cpPub);
|
||||
|
||||
free(keys->rsa.cciCfaPvt);
|
||||
free(keys->rsa.cciCfaPub);
|
||||
|
||||
free(keys->rsa.acexPvt);
|
||||
free(keys->rsa.acexPub);
|
||||
free(keys->rsa.cxiHdrPub);
|
||||
free(keys->rsa.cxiHdrPvt);
|
||||
Rsa2048Key_Free(&keys->rsa.xs);
|
||||
Rsa2048Key_Free(&keys->rsa.cp);
|
||||
Rsa2048Key_Free(&keys->rsa.cciCfa);
|
||||
Rsa2048Key_Free(&keys->rsa.acex);
|
||||
Rsa2048Key_Free(&keys->rsa.cxi);
|
||||
|
||||
// Certs
|
||||
free(keys->certs.caCert);
|
||||
@@ -378,30 +353,6 @@ int SetSystemFixedKey(keys_struct *keys, const u8 *key)
|
||||
return CopyData(&keys->aes.systemFixedKey,key,16);
|
||||
}
|
||||
|
||||
int SetTIK_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return SetRsaKeySet(&keys->rsa.xsPvt,priv_exp,&keys->rsa.xsPub,modulus);
|
||||
}
|
||||
|
||||
int SetTMD_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return SetRsaKeySet(&keys->rsa.cpPvt,priv_exp,&keys->rsa.cpPub,modulus);
|
||||
}
|
||||
|
||||
int Set_CCI_CFA_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return SetRsaKeySet(&keys->rsa.cciCfaPvt,priv_exp,&keys->rsa.cciCfaPub,modulus);
|
||||
}
|
||||
|
||||
int SetAccessDesc_RsaKey(keys_struct *keys, const u8 *priv_exp, const u8 *modulus)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
return SetRsaKeySet(&keys->rsa.acexPvt,priv_exp,&keys->rsa.acexPub,modulus);
|
||||
}
|
||||
|
||||
int SetCaCert(keys_struct *keys, const u8 *cert)
|
||||
{
|
||||
if(!keys) return -1;
|
||||
@@ -418,3 +369,27 @@ int SetTmdCert(keys_struct *keys, const u8 *cert)
|
||||
if(!keys) return -1;
|
||||
return CopyData(&keys->certs.cpCert,cert,0x400);
|
||||
}
|
||||
|
||||
void Rsa2048Key_Alloc(rsa2048_key* key)
|
||||
{
|
||||
key->pub = malloc(RSA_2048_KEY_SIZE);
|
||||
key->pvt = malloc(RSA_2048_KEY_SIZE);
|
||||
}
|
||||
|
||||
void Rsa2048Key_Free(rsa2048_key* key)
|
||||
{
|
||||
free(key->pub);
|
||||
free(key->pvt);
|
||||
}
|
||||
|
||||
void Rsa2048Key_Set(rsa2048_key* key, const u8* pvt, const u8* pub)
|
||||
{
|
||||
memcpy(key->pub, pub, RSA_2048_KEY_SIZE);
|
||||
memcpy(key->pvt, pvt, RSA_2048_KEY_SIZE);
|
||||
}
|
||||
|
||||
bool Rsa2048Key_CanSign(const rsa2048_key* key)
|
||||
{
|
||||
static const u8 rsa2048[RSA_2048_KEY_SIZE] = { 0 };
|
||||
return memcmp(key->pub, rsa2048, RSA_2048_KEY_SIZE) != 0 || memcmp(key->pvt, rsa2048, RSA_2048_KEY_SIZE) != 0;
|
||||
}
|
||||
+17
-12
@@ -31,11 +31,18 @@ typedef enum
|
||||
|
||||
// Structs
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *pub;
|
||||
u8 *pvt;
|
||||
} rsa2048_key;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pki_keyset keyset;
|
||||
bool keysetLoaded;
|
||||
bool dumpkeys;
|
||||
bool ignore_sign;
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -60,23 +67,16 @@ typedef struct
|
||||
|
||||
struct
|
||||
{
|
||||
bool isFalseSign;
|
||||
// CIA RSA
|
||||
u8 *cpPvt;
|
||||
u8 *cpPub;
|
||||
u8 *xsPvt;
|
||||
u8 *xsPub;
|
||||
rsa2048_key cp;
|
||||
rsa2048_key xs;
|
||||
|
||||
// CCI/CFA
|
||||
u8 *cciCfaPvt;
|
||||
u8 *cciCfaPub;
|
||||
rsa2048_key cciCfa;
|
||||
|
||||
// CXI
|
||||
bool requiresPresignedDesc;
|
||||
u8 *acexPvt;
|
||||
u8 *acexPub;
|
||||
u8 *cxiHdrPub;
|
||||
u8 *cxiHdrPvt;
|
||||
rsa2048_key acex;
|
||||
rsa2048_key cxi;
|
||||
} rsa;
|
||||
|
||||
struct
|
||||
@@ -97,3 +97,8 @@ int SetCommonKey(keys_struct *keys, const u8 *key, u8 Index);
|
||||
int SetCurrentCommonKey(keys_struct *keys, u8 Index);
|
||||
int SetNormalKey(keys_struct *keys, const u8 *key);
|
||||
int SetSystemFixedKey(keys_struct *keys, const u8 *key);
|
||||
|
||||
void Rsa2048Key_Alloc(rsa2048_key* key);
|
||||
void Rsa2048Key_Free(rsa2048_key* key);
|
||||
void Rsa2048Key_Set(rsa2048_key* key, const u8* pvt, const u8* pub);
|
||||
bool Rsa2048Key_CanSign(const rsa2048_key* key);
|
||||
+40
-17
@@ -36,17 +36,27 @@ bool IsValidProductCode(char *ProductCode, bool FreeProductCode);
|
||||
// Code
|
||||
int SignCFA(ncch_hdr *hdr, keys_struct *keys)
|
||||
{
|
||||
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfaPub,keys->rsa.cciCfaPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
|
||||
if (RsaSignVerify(GetNcchHdrData(hdr), GetNcchHdrDataLen(hdr), GetNcchHdrSig(hdr), keys->rsa.cciCfa.pub, keys->rsa.cciCfa.pvt, RSA_2048_SHA256, CTR_RSA_SIGN) != 0)
|
||||
{
|
||||
printf("[NCCH WARNING] Failed to sign CFA header\n");
|
||||
memset(GetNcchHdrSig(hdr), 0xFF, 0x100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CheckCFASignature(ncch_hdr *hdr, keys_struct *keys)
|
||||
{
|
||||
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfaPub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
|
||||
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cciCfa.pub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
|
||||
}
|
||||
|
||||
int SignCXI(ncch_hdr *hdr, keys_struct *keys)
|
||||
{
|
||||
return RsaSignVerify(GetNcchHdrData(hdr),GetNcchHdrDataLen(hdr),GetNcchHdrSig(hdr),keys->rsa.cxiHdrPub,keys->rsa.cxiHdrPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
|
||||
if (RsaSignVerify(GetNcchHdrData(hdr), GetNcchHdrDataLen(hdr), GetNcchHdrSig(hdr), keys->rsa.cxi.pub, keys->rsa.cxi.pvt, RSA_2048_SHA256, CTR_RSA_SIGN) != 0)
|
||||
{
|
||||
printf("[NCCH WARNING] Failed to sign CXI header\n");
|
||||
memset(GetNcchHdrSig(hdr), 0xFF, 0x100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CheckCXISignature(ncch_hdr *hdr, u8 *pubk)
|
||||
@@ -748,11 +758,14 @@ int VerifyNcch(u8 *ncch, keys_struct *keys, bool CheckHash, bool SuppressOutput)
|
||||
}
|
||||
|
||||
if(IsCfa(hdr)){
|
||||
if(CheckCFASignature(hdr,keys) != Good && !keys->rsa.isFalseSign){
|
||||
if(CheckCFASignature(hdr,keys) != Good){
|
||||
if(!SuppressOutput)
|
||||
fprintf(stderr,"[NCCH ERROR] CFA Sigcheck Failed\n");
|
||||
free(ncchInfo);
|
||||
return NCCH_HDR_SIG_BAD;
|
||||
fprintf(keys->ignore_sign ? stdout :stderr,"[NCCH %s] CFA Sigcheck Failed\n", keys->ignore_sign ? "WARNING" : "ERROR");
|
||||
if (!keys->ignore_sign)
|
||||
{
|
||||
free(ncchInfo);
|
||||
return NCCH_HDR_SIG_BAD;
|
||||
}
|
||||
}
|
||||
if(!ncchInfo->romfsSize){
|
||||
if(!SuppressOutput)
|
||||
@@ -813,19 +826,29 @@ int VerifyNcch(u8 *ncch, keys_struct *keys, bool CheckHash, bool SuppressOutput)
|
||||
if(IsNcchEncrypted(hdr))
|
||||
CryptNcchRegion((u8*)acexDesc,ncchInfo->acexSize,ncchInfo->exhdrSize,ncchInfo->titleId,keys->aes.ncchKey0,ncch_exhdr);
|
||||
|
||||
if(CheckAccessDescSignature(acexDesc,keys) != 0 && !keys->rsa.isFalseSign){
|
||||
if(!SuppressOutput) fprintf(stderr,"[NCCH ERROR] AccessDesc Sigcheck Failed\n");
|
||||
free(ncchInfo);
|
||||
free(acexDesc);
|
||||
return ACCESSDESC_SIG_BAD;
|
||||
|
||||
if(CheckAccessDescSignature(acexDesc,keys) != Good){
|
||||
if (!SuppressOutput)
|
||||
fprintf(keys->false_sign? stdout : stderr, "[NCCH %s] AccessDesc Sigcheck Failed\n", keys->ignore_sign ? "WARNING" : "ERROR");
|
||||
if (!keys->ignore_sign)
|
||||
{
|
||||
free(ncchInfo);
|
||||
free(acexDesc);
|
||||
return ACCESSDESC_SIG_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
if(CheckCXISignature(hdr,GetAcexNcchPubKey(acexDesc)) != 0 && !keys->rsa.isFalseSign){
|
||||
if(!SuppressOutput) fprintf(stderr,"[NCCH ERROR] CXI Header Sigcheck Failed\n");
|
||||
free(ncchInfo);
|
||||
free(acexDesc);
|
||||
return NCCH_HDR_SIG_BAD;
|
||||
if(CheckCXISignature(hdr,GetAcexNcchPubKey(acexDesc)) != Good){
|
||||
if (!SuppressOutput)
|
||||
fprintf(keys->ignore_sign ? stdout : stderr,"[NCCH %s] CXI Header Sigcheck Failed\n", keys->ignore_sign ? "WARNING" : "ERROR");
|
||||
if (!keys->ignore_sign)
|
||||
{
|
||||
free(ncchInfo);
|
||||
free(acexDesc);
|
||||
return NCCH_HDR_SIG_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!CheckHash)
|
||||
|
||||
+6
-1
@@ -579,7 +579,12 @@ int GenCciHdr(cci_settings *set)
|
||||
|
||||
|
||||
// Sign Header
|
||||
RsaSignVerify(&hdr->magic,sizeof(cci_hdr)-RSA_2048_KEY_SIZE,hdr->signature,set->keys->rsa.cciCfaPub,set->keys->rsa.cciCfaPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
|
||||
if (RsaSignVerify(&hdr->magic, sizeof(cci_hdr) - RSA_2048_KEY_SIZE, hdr->signature, set->keys->rsa.cciCfa.pub, set->keys->rsa.cciCfa.pvt, RSA_2048_SHA256, CTR_RSA_SIGN) != 0)
|
||||
{
|
||||
printf("[NCSD WARNING] Failed to sign header\n");
|
||||
memset(hdr->signature, 0xFF, 0x100);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+7
-1
@@ -81,7 +81,13 @@ int SignTicketHeader(buffer_struct *tik, keys_struct *keys)
|
||||
clrmem(sig,sizeof(tik_signature));
|
||||
u32_to_u8(sig->sigType,RSA_2048_SHA256,BE);
|
||||
|
||||
return RsaSignVerify(data,len,sig->data,keys->rsa.xsPub,keys->rsa.xsPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
|
||||
if (RsaSignVerify(data, len, sig->data, keys->rsa.xs.pub, keys->rsa.xs.pvt, RSA_2048_SHA256, CTR_RSA_SIGN) != 0)
|
||||
{
|
||||
printf("[TIK WARNING] Failed to sign header\n");
|
||||
memset(sig->data, 0xFF, 0x100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CryptTitleKey(u8 *input, u8 *output, u8 *titleId, keys_struct *keys, u8 mode)
|
||||
|
||||
+7
-1
@@ -71,7 +71,13 @@ int SignTMDHeader(tmd_hdr *hdr, tmd_signature *sig, keys_struct *keys)
|
||||
clrmem(sig,sizeof(tmd_signature));
|
||||
u32_to_u8(sig->sigType,RSA_2048_SHA256,BE);
|
||||
|
||||
return RsaSignVerify((u8*)hdr,sizeof(tmd_hdr),sig->data,keys->rsa.cpPub,keys->rsa.cpPvt,RSA_2048_SHA256,CTR_RSA_SIGN);
|
||||
if (RsaSignVerify((u8*)hdr, sizeof(tmd_hdr), sig->data, keys->rsa.cp.pub, keys->rsa.cp.pvt, RSA_2048_SHA256, CTR_RSA_SIGN) != 0)
|
||||
{
|
||||
printf("[TMD WARNING] Failed to sign header\n");
|
||||
memset(sig->data, 0xFF, 0x100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetupTMDInfoRecord(tmd_content_info_record *info_record, u8 *content_record, u16 ContentCount)
|
||||
|
||||
@@ -85,6 +85,7 @@ void SetDefaults(user_settings *set)
|
||||
// Target Info
|
||||
set->common.keys.keyset = pki_TEST;
|
||||
set->common.keys.accessDescSign.presetType = desc_NotSpecified;
|
||||
set->common.keys.ignore_sign = false;
|
||||
|
||||
// Build NCCH Info
|
||||
set->ncch.useSecCrypto = true;
|
||||
@@ -195,6 +196,7 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set)
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
/*
|
||||
else if (strcmp(argv[i], "-ckeyid") == 0) {
|
||||
if (ParamNum != 1) {
|
||||
PrintArgReqParam(argv[i], 1);
|
||||
@@ -222,6 +224,7 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set)
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
*/
|
||||
else if (strcmp(argv[i], "-showkeys") == 0) {
|
||||
if (ParamNum) {
|
||||
PrintNoNeedParam(argv[i]);
|
||||
@@ -230,12 +233,12 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set)
|
||||
set->common.keys.dumpkeys = true;
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(argv[i], "-fsign") == 0) {
|
||||
else if (strcmp(argv[i], "-ignoresign") == 0) {
|
||||
if (ParamNum) {
|
||||
PrintNoNeedParam(argv[i]);
|
||||
return USR_BAD_ARG;
|
||||
}
|
||||
set->common.keys.rsa.isFalseSign = true;
|
||||
set->common.keys.ignore_sign = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -949,10 +952,11 @@ void DisplayExtendedHelp(char *app_name)
|
||||
printf(" 't' Test(false) Keys & prod Certs\n");
|
||||
printf(" 'd' Development Keys & Certs\n");
|
||||
printf(" 'p' Production Keys & Certs\n");
|
||||
printf(" -ckeyid <index> Override the automatic common key selection\n");
|
||||
printf(" -ncchseckey <index> Ncch keyX index ('0'=1.0+, '1'=7.0+)\n");
|
||||
//printf(" -ckeyid <index> Override the automatic common key selection\n");
|
||||
//printf(" -ncchseckey <index> Ncch keyX index ('0'=1.0+, '1'=7.0+)\n");
|
||||
printf(" -showkeys Display the loaded key chain\n");
|
||||
printf(" -fsign Ignore invalid signatures\n");
|
||||
//printf(" -fsign False sign digital signatures\n");
|
||||
printf(" -ignoresign Ignore invalid signatures\n");
|
||||
printf("NCCH OPTIONS:\n");
|
||||
printf(" -elf <file> ELF file\n");
|
||||
printf(" -icon <file> Icon file\n");
|
||||
|
||||
Reference in New Issue
Block a user