mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-05 00:39:04 +00:00
big update
lots cleaned, added cia to cci conv, it 's called a block, separated reading from building, improved ncch keyx stuff, and basic verbose for keys, elf checking and romfs
This commit is contained in:
+198
-89
@@ -1,41 +1,44 @@
|
||||
#include "lib.h"
|
||||
#include "ncch.h"
|
||||
#include "exheader.h"
|
||||
#include "exefs.h"
|
||||
#include "certs.h"
|
||||
#include "cia.h"
|
||||
#include "tik.h"
|
||||
#include "tmd.h"
|
||||
#include "titleid.h"
|
||||
|
||||
#include "srl.h"
|
||||
#include "ncsd.h"
|
||||
#include "ncsd_read.h"
|
||||
#include "ncch_read.h"
|
||||
#include "exheader_read.h"
|
||||
#include "exefs_read.h"
|
||||
|
||||
#include "cia_build.h"
|
||||
#include "cia_read.h"
|
||||
#include "tik_build.h"
|
||||
#include "tmd_build.h"
|
||||
#include "titleid.h"
|
||||
#include "certs.h"
|
||||
|
||||
const int CIA_ALIGN_SIZE = 0x40;
|
||||
const int CIA_CONTENT_ALIGN = 0x10;
|
||||
|
||||
// Private Prototypes
|
||||
/* cia_settings tools */
|
||||
void init_CIASettings(cia_settings *set);
|
||||
void free_CIASettings(cia_settings *set);
|
||||
int get_CIASettings(cia_settings *ciaset, user_settings *usrset);
|
||||
void InitCiaSettings(cia_settings *set);
|
||||
void FreeCiaSettings(cia_settings *set);
|
||||
int GetCiaSettings(cia_settings *ciaset, user_settings *usrset);
|
||||
|
||||
int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset);
|
||||
int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset);
|
||||
int GetCIADataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 *key);
|
||||
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 *key);
|
||||
int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key);
|
||||
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key);
|
||||
int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset);
|
||||
int ImportNcchContent(cia_settings *ciaset);
|
||||
int GetSettingsFromSrl(cia_settings *ciaset);
|
||||
int GetSettingsFromCci(cia_settings *ciaset);
|
||||
|
||||
u16 SetupVersion(u16 Major, u16 Minor, u16 Micro);
|
||||
u16 SetupVersion(u16 major, u16 minor, u16 micro);
|
||||
|
||||
void GetContentHashes(cia_settings *ciaset);
|
||||
void EncryptContent(cia_settings *ciaset);
|
||||
|
||||
int BuildCIA_CertChain(cia_settings *ciaset);
|
||||
int BuildCIA_Header(cia_settings *ciaset);
|
||||
int BuildCiaCertChain(cia_settings *ciaset);
|
||||
int BuildCiaHdr(cia_settings *ciaset);
|
||||
|
||||
int WriteCIAtoFile(cia_settings *ciaset);
|
||||
|
||||
int CryptContent(u8 *EncBuffer,u8 *DecBuffer,u64 size,u8 *title_key, u16 index, u8 mode);
|
||||
int WriteCiaToFile(cia_settings *ciaset);
|
||||
|
||||
|
||||
int build_CIA(user_settings *usrset)
|
||||
@@ -50,8 +53,8 @@ int build_CIA(user_settings *usrset)
|
||||
}
|
||||
|
||||
// Get Settings
|
||||
init_CIASettings(ciaset);
|
||||
result = get_CIASettings(ciaset,usrset);
|
||||
InitCiaSettings(ciaset);
|
||||
result = GetCiaSettings(ciaset,usrset);
|
||||
if(result) goto finish;
|
||||
|
||||
// Create Output File
|
||||
@@ -65,7 +68,7 @@ int build_CIA(user_settings *usrset)
|
||||
// Create CIA Sections
|
||||
|
||||
/* Certificate Chain */
|
||||
result = BuildCIA_CertChain(ciaset);
|
||||
result = BuildCiaCertChain(ciaset);
|
||||
if(result) goto finish;
|
||||
|
||||
/* Ticket */
|
||||
@@ -77,28 +80,28 @@ int build_CIA(user_settings *usrset)
|
||||
if(result) goto finish;
|
||||
|
||||
/* CIA Header */
|
||||
result = BuildCIA_Header(ciaset);
|
||||
result = BuildCiaHdr(ciaset);
|
||||
if(result) goto finish;
|
||||
|
||||
/* Write To File */
|
||||
result = WriteCIAtoFile(ciaset);
|
||||
result = WriteCiaToFile(ciaset);
|
||||
if(result) goto finish;
|
||||
|
||||
finish:
|
||||
if(result != FAILED_TO_CREATE_OUTFILE && ciaset->out)
|
||||
fclose(ciaset->out);
|
||||
|
||||
free_CIASettings(ciaset);
|
||||
FreeCiaSettings(ciaset);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void init_CIASettings(cia_settings *set)
|
||||
void InitCiaSettings(cia_settings *set)
|
||||
{
|
||||
memset(set,0,sizeof(cia_settings));
|
||||
}
|
||||
|
||||
void free_CIASettings(cia_settings *set)
|
||||
void FreeCiaSettings(cia_settings *set)
|
||||
{
|
||||
if(set->content.filePtrs){
|
||||
for(u32 i = 1; i < set->content.count; i++){
|
||||
@@ -117,7 +120,7 @@ void free_CIASettings(cia_settings *set)
|
||||
free(set);
|
||||
}
|
||||
|
||||
int get_CIASettings(cia_settings *ciaset, user_settings *usrset)
|
||||
int GetCiaSettings(cia_settings *ciaset, user_settings *usrset)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
@@ -125,26 +128,21 @@ int get_CIASettings(cia_settings *ciaset, user_settings *usrset)
|
||||
result = GetSettingsFromUsrset(ciaset,usrset);
|
||||
|
||||
if(usrset->common.workingFileType == infile_ncch){
|
||||
result = GetSettingsFromNcch0(ciaset,0);
|
||||
if(result)
|
||||
if((result = GetSettingsFromNcch0(ciaset,0)) != 0)
|
||||
return result;
|
||||
result = GetContentFilePtrs(ciaset,usrset);
|
||||
if(result)
|
||||
if((result = GetContentFilePtrs(ciaset,usrset)) != 0)
|
||||
return result;
|
||||
result = ImportNcchContent(ciaset);
|
||||
if(result)
|
||||
if((result = ImportNcchContent(ciaset)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
else if(usrset->common.workingFileType == infile_srl){
|
||||
result = GetSettingsFromSrl(ciaset);
|
||||
if(result)
|
||||
if((result = GetSettingsFromSrl(ciaset)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
else if(usrset->common.workingFileType == infile_ncsd){
|
||||
result = GetSettingsFromCci(ciaset);
|
||||
if(result)
|
||||
if((result = GetSettingsFromCci(ciaset)) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -165,7 +163,9 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
|
||||
ciaset->ciaSections.content.size = usrset->common.workingFile.size;
|
||||
usrset->common.workingFile.buffer = NULL;
|
||||
ciaset->ciaSections.content.size = 0;
|
||||
|
||||
ciaset->content.includeUpdateNcch = usrset->cia.includeUpdateNcch;
|
||||
ciaset->verbose = usrset->common.verbose;
|
||||
|
||||
u32_to_u8(ciaset->tmd.titleType,TYPE_CTR,BE);
|
||||
ciaset->content.encryptCia = usrset->common.rsfSet.Option.EnableCrypt;
|
||||
ciaset->content.IsDlc = usrset->cia.DlcContent;
|
||||
@@ -183,16 +183,19 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
|
||||
|
||||
// Ticket Data
|
||||
rndset(ciaset->tik.ticketId,8);
|
||||
clrmem(ciaset->tik.deviceId,4);
|
||||
clrmem(ciaset->tik.eshopAccId,4);
|
||||
u32_to_u8(ciaset->tik.deviceId,usrset->cia.deviceId,BE);
|
||||
u32_to_u8(ciaset->tik.eshopAccId,usrset->cia.eshopAccId,BE);
|
||||
ciaset->tik.licenceType = 0;
|
||||
ciaset->tik.audit = 0;
|
||||
|
||||
if(usrset->cia.randomTitleKey)
|
||||
rndset(ciaset->common.titleKey,16);
|
||||
rndset(ciaset->common.titleKey,AES_128_KEY_SIZE);
|
||||
else
|
||||
clrmem(ciaset->common.titleKey,16);
|
||||
clrmem(ciaset->common.titleKey,AES_128_KEY_SIZE);
|
||||
|
||||
if(ciaset->verbose)
|
||||
memdump(stdout,"[CIA] CIA title key: ",ciaset->common.titleKey,AES_128_KEY_SIZE);
|
||||
|
||||
ciaset->tik.formatVersion = 1;
|
||||
|
||||
int result = GenCertChildIssuer(ciaset->tik.issuer,ciaset->keys->certs.xsCert);
|
||||
@@ -217,33 +220,29 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
|
||||
|
||||
u8 *ncch0 = (u8*)(ciaset->ciaSections.content.buffer+ncch0_offset);
|
||||
|
||||
if(!IsNCCH(NULL,ncch0)){
|
||||
if(!IsNcch(NULL,ncch0)){
|
||||
fprintf(stderr,"[CIA ERROR] Content0 is not NCCH\n");
|
||||
return CIA_INVALID_NCCH0;
|
||||
}
|
||||
|
||||
/* Get Ncch0 Header */
|
||||
ncch_hdr *hdr = NULL;
|
||||
hdr = GetNCCH_CommonHDR(hdr,NULL,ncch0);
|
||||
if(IsCfa(hdr)){
|
||||
ciaset->content.IsCfa = true;
|
||||
}
|
||||
ncch_hdr *hdr = (ncch_hdr*)ncch0;
|
||||
ciaset->content.IsCfa = IsCfa(hdr);
|
||||
|
||||
ciaset->content.offset[0] = 0;
|
||||
ciaset->content.size[0] = align(GetNCCH_MediaSize(hdr)*GetNCCH_MediaUnitSize(hdr),0x10);
|
||||
ciaset->content.size[0] = align(GetNcchSize(hdr),0x10);
|
||||
ciaset->content.totalSize = ciaset->content.size[0];
|
||||
|
||||
/* Get Ncch0 Import Context */
|
||||
ncch_struct *ncch_ctx = malloc(sizeof(ncch_struct));
|
||||
if(!ncch_ctx){
|
||||
ncch_info *info = calloc(1,sizeof(ncch_info));
|
||||
if(!info){
|
||||
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
|
||||
return MEM_ERROR;
|
||||
}
|
||||
memset(ncch_ctx,0x0,sizeof(ncch_struct));
|
||||
GetNCCHStruct(ncch_ctx,hdr);
|
||||
GetNcchInfo(info,hdr);
|
||||
|
||||
/* Verify Ncch0 (Sig&Hash Checks) */
|
||||
int result = VerifyNCCH(ncch0,ciaset->keys,false,true);
|
||||
int result = VerifyNcch(ncch0,ciaset->keys,false,true);
|
||||
if(result == UNABLE_TO_LOAD_NCCH_KEY){
|
||||
ciaset->content.keyNotFound = true;
|
||||
if(!ciaset->content.IsCfa){
|
||||
@@ -261,31 +260,35 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
|
||||
|
||||
|
||||
/* Getting ncch key */
|
||||
ncch_key_type keyType = GetNCCHKeyType(hdr);
|
||||
u8 *ncchkey = NULL;
|
||||
if(!ciaset->content.keyNotFound){
|
||||
SetNcchUnfixedKeys(ciaset->keys,ncch0);
|
||||
ncchkey = GetNCCHKey0(keyType,ciaset->keys);
|
||||
if(!ciaset->content.keyNotFound || IsNcchEncrypted(hdr)){
|
||||
SetNcchKeys(ciaset->keys,hdr);
|
||||
ncchkey = ciaset->keys->aes.ncchKey0;
|
||||
if(ciaset->verbose){
|
||||
printf("[CIA] NCCH AES keys:\n");
|
||||
memdump(stdout," > key0: ",ciaset->keys->aes.ncchKey0,AES_128_KEY_SIZE);
|
||||
memdump(stdout," > key1: ",ciaset->keys->aes.ncchKey1,AES_128_KEY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get TMD Data from ncch */
|
||||
result = GetCIADataFromNcch(ciaset,ncch0,ncch_ctx,ncchkey); // Data For TMD
|
||||
result = GetTmdDataFromNcch(ciaset,ncch0,info,ncchkey); // Data For TMD
|
||||
if(result) goto finish;
|
||||
/* Get META Region from ncch */
|
||||
result = GetMetaRegion(ciaset,ncch0,ncch_ctx,ncchkey); // Meta Region
|
||||
result = GetMetaRegion(ciaset,ncch0,info,ncchkey); // Meta Region
|
||||
/* Finish */
|
||||
finish:
|
||||
/* Return */
|
||||
free(ncch_ctx);
|
||||
free(info);
|
||||
return result;
|
||||
}
|
||||
|
||||
int GetCIADataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 *key)
|
||||
int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key)
|
||||
{
|
||||
extended_hdr *exhdr = malloc(sizeof(extended_hdr));
|
||||
memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr));
|
||||
if(key != NULL)
|
||||
CryptNCCHSection((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx,key,ncch_exhdr);
|
||||
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),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)
|
||||
@@ -318,28 +321,26 @@ int GetCIADataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8
|
||||
ciaset->common.titleVersion[VER_MAJOR] = GetRemasterVersion_frm_exhdr(exhdr);
|
||||
}
|
||||
|
||||
u16 version = SetupVersion(ciaset->common.titleVersion[VER_MAJOR],ciaset->common.titleVersion[VER_MINOR],ciaset->common.titleVersion[VER_MICRO]);
|
||||
ciaset->tik.version = version;
|
||||
ciaset->tmd.version = version;
|
||||
ciaset->tmd.version = ciaset->tik.version = SetupVersion(ciaset->common.titleVersion[VER_MAJOR],ciaset->common.titleVersion[VER_MINOR],ciaset->common.titleVersion[VER_MICRO]);
|
||||
|
||||
free(exhdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 *key)
|
||||
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_info *info, u8 *key)
|
||||
{
|
||||
if(ciaset->content.IsCfa || ciaset->content.keyNotFound)
|
||||
return 0;
|
||||
|
||||
extended_hdr *exhdr = malloc(sizeof(extended_hdr));
|
||||
memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr));
|
||||
memcpy(exhdr,ncch+info->exhdrOffset,sizeof(extended_hdr));
|
||||
if(key != NULL)
|
||||
CryptNCCHSection((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx,key,ncch_exhdr);
|
||||
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,info,key,ncch_exhdr);
|
||||
|
||||
exefs_hdr *exefsHdr = malloc(sizeof(exefs_hdr));
|
||||
memcpy(exefsHdr,ncch+ncch_ctx->exefsOffset,sizeof(exefs_hdr));
|
||||
memcpy(exefsHdr,ncch+info->exefsOffset,sizeof(exefs_hdr));
|
||||
if(key != NULL)
|
||||
CryptNCCHSection((u8*)exefsHdr,sizeof(exefs_hdr),0,ncch_ctx,key,ncch_exefs);
|
||||
CryptNcchRegion((u8*)exefsHdr,sizeof(exefs_hdr),0,info,key,ncch_exefs);
|
||||
|
||||
u32 icon_size = 0;
|
||||
u32 icon_offset = 0;
|
||||
@@ -349,7 +350,7 @@ int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 *key
|
||||
icon_offset = u8_to_u32(exefsHdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ciaset->ciaSections.meta.size = sizeof(cia_metadata) + icon_size;
|
||||
ciaset->ciaSections.meta.buffer = malloc(ciaset->ciaSections.meta.size);
|
||||
if(!ciaset->ciaSections.meta.buffer){
|
||||
@@ -362,9 +363,9 @@ int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_struct *ncch_ctx, u8 *key
|
||||
GetCoreVersion_frm_exhdr(hdr->coreVersion,exhdr);
|
||||
if(icon_size > 0){
|
||||
u8 *IconDestPos = (ciaset->ciaSections.meta.buffer + sizeof(cia_metadata));
|
||||
memcpy(IconDestPos,ncch+ncch_ctx->exefsOffset+icon_offset,icon_size);
|
||||
memcpy(IconDestPos,ncch+info->exefsOffset+icon_offset,icon_size);
|
||||
if(key != NULL)
|
||||
CryptNCCHSection(IconDestPos,icon_size,icon_offset,ncch_ctx,key,ncch_exefs);
|
||||
CryptNcchRegion(IconDestPos,icon_size,icon_offset,info,key,ncch_exefs);
|
||||
//memdump(stdout,"Icon: ",IconDestPos,0x10);
|
||||
}
|
||||
|
||||
@@ -389,7 +390,7 @@ int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset)
|
||||
fprintf(stderr,"[CIA ERROR] Failed to open \"%s\"\n",usrset->common.contentPath[i]);
|
||||
return FAILED_TO_OPEN_FILE;
|
||||
}
|
||||
ciaset->content.fileSize[j] = GetFileSize_u64(usrset->common.contentPath[i]);
|
||||
ciaset->content.fileSize[j] = GetFileSize64(usrset->common.contentPath[i]);
|
||||
ciaset->content.filePtrs[j] = fopen(usrset->common.contentPath[i],"rb");
|
||||
|
||||
if(usrset->cia.contentId[i] > MAX_U32)
|
||||
@@ -400,10 +401,10 @@ int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset)
|
||||
ciaset->content.index[j] = (u16)i;
|
||||
|
||||
// Get Data from ncch HDR
|
||||
GetNCCH_CommonHDR(hdr,ciaset->content.filePtrs[j],NULL);
|
||||
ReadNcchHdr(hdr,ciaset->content.filePtrs[j]);
|
||||
|
||||
// Get Size
|
||||
u64 calcSize = (u64)GetNCCH_MediaSize(hdr) * (u64)GetNCCH_MediaUnitSize(hdr);
|
||||
u64 calcSize = GetNcchSize(hdr);
|
||||
if(calcSize != ciaset->content.fileSize[j]){
|
||||
fprintf(stderr,"[CIA ERROR] \"%s\" is corrupt\n",usrset->common.contentPath[i]);
|
||||
return FAILED_TO_OPEN_FILE;
|
||||
@@ -447,7 +448,7 @@ int ImportNcchContent(cia_settings *ciaset)
|
||||
// Import
|
||||
u8 *ncchpos = (u8*)(ciaset->ciaSections.content.buffer+ciaset->content.offset[i]);
|
||||
|
||||
ReadFile_64(ncchpos, ciaset->content.fileSize[i], 0, ciaset->content.filePtrs[i]);
|
||||
ReadFile64(ncchpos, ciaset->content.fileSize[i], 0, ciaset->content.filePtrs[i]);
|
||||
if(ModifyNcchIds(ncchpos, NULL, ncch0hdr->programId, ciaset->keys) != 0)
|
||||
return -1;
|
||||
|
||||
@@ -528,6 +529,11 @@ int GetSettingsFromCci(cia_settings *ciaset)
|
||||
cciContentOffsets[0] = ncch0_offset;
|
||||
for(int i = 1; i < 8; i++){
|
||||
if(GetPartitionSize(ciaset->ciaSections.content.buffer,i)){
|
||||
ncch_hdr *ncchHdr = (ncch_hdr*)GetPartition(ciaset->ciaSections.content.buffer, i);
|
||||
|
||||
if(IsUpdateCfa(ncchHdr) && !ciaset->content.includeUpdateNcch)
|
||||
continue;
|
||||
|
||||
cciContentOffsets[j] = GetPartitionOffset(ciaset->ciaSections.content.buffer,i);
|
||||
|
||||
// Get Size
|
||||
@@ -557,9 +563,9 @@ int GetSettingsFromCci(cia_settings *ciaset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 SetupVersion(u16 Major, u16 Minor, u16 Micro)
|
||||
u16 SetupVersion(u16 major, u16 minor, u16 micro)
|
||||
{
|
||||
return (((Major << 10) & 0xFC00) | ((Minor << 4) & 0x3F0) | (Micro & 0xf));
|
||||
return (((major << 10) & 0xFC00) | ((minor << 4) & 0x3F0) | (micro & 0xf));
|
||||
}
|
||||
|
||||
void GetContentHashes(cia_settings *ciaset)
|
||||
@@ -577,7 +583,7 @@ void EncryptContent(cia_settings *ciaset)
|
||||
}
|
||||
}
|
||||
|
||||
int BuildCIA_CertChain(cia_settings *ciaset)
|
||||
int BuildCiaCertChain(cia_settings *ciaset)
|
||||
{
|
||||
ciaset->ciaSections.certChain.size = GetCertSize(ciaset->keys->certs.caCert) + GetCertSize(ciaset->keys->certs.xsCert) + GetCertSize(ciaset->keys->certs.cpCert);
|
||||
ciaset->ciaSections.certChain.buffer = malloc(ciaset->ciaSections.certChain.size);
|
||||
@@ -591,7 +597,7 @@ int BuildCIA_CertChain(cia_settings *ciaset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BuildCIA_Header(cia_settings *ciaset)
|
||||
int BuildCiaHdr(cia_settings *ciaset)
|
||||
{
|
||||
// Allocating memory for header
|
||||
ciaset->ciaSections.ciaHdr.size = sizeof(cia_hdr);
|
||||
@@ -644,7 +650,7 @@ int BuildCIA_Header(cia_settings *ciaset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WriteCIAtoFile(cia_settings *ciaset)
|
||||
int WriteCiaToFile(cia_settings *ciaset)
|
||||
{
|
||||
WriteBuffer(ciaset->ciaSections.ciaHdr.buffer,ciaset->ciaSections.ciaHdr.size,0,ciaset->out);
|
||||
WriteBuffer(ciaset->ciaSections.certChain.buffer,ciaset->ciaSections.certChain.size,ciaset->ciaSections.certChainOffset,ciaset->out);
|
||||
@@ -656,7 +662,7 @@ int WriteCIAtoFile(cia_settings *ciaset)
|
||||
}
|
||||
|
||||
|
||||
int CryptContent(u8 *EncBuffer,u8 *DecBuffer,u64 size,u8 *title_key, u16 index, u8 mode)
|
||||
int CryptContent(u8 *enc, u8 *dec, u64 size, u8 *title_key, u16 index, u8 mode)
|
||||
{
|
||||
//generating IV
|
||||
u8 iv[16];
|
||||
@@ -667,7 +673,110 @@ int CryptContent(u8 *EncBuffer,u8 *DecBuffer,u64 size,u8 *title_key, u16 index,
|
||||
ctr_aes_context ctx;
|
||||
memset(&ctx,0x0,sizeof(ctr_aes_context));
|
||||
ctr_init_aes_cbc(&ctx,title_key,iv,mode);
|
||||
if(mode == ENC) ctr_aes_cbc(&ctx,DecBuffer,EncBuffer,size,ENC);
|
||||
else ctr_aes_cbc(&ctx,EncBuffer,DecBuffer,size,DEC);
|
||||
if(mode == ENC) ctr_aes_cbc(&ctx,dec,enc,size,ENC);
|
||||
else ctr_aes_cbc(&ctx,enc,dec,size,DEC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsCia(u8 *cia)
|
||||
{
|
||||
if(!cia)
|
||||
return false;
|
||||
|
||||
cia_hdr *hdr = (cia_hdr*)cia;
|
||||
|
||||
if(u8_to_u32(hdr->hdrSize,LE) != sizeof(cia_hdr) || u8_to_u16(hdr->type,LE) != 0 || u8_to_u16(hdr->version,LE) != 0)
|
||||
return false;
|
||||
|
||||
if(!GetCiaCertSize(hdr) || !GetCiaTikSize(hdr) || !GetCiaTmdSize(hdr) || !GetCiaContentSize(hdr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 GetCiaCertOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 hdrSize = u8_to_u32(hdr->hdrSize,LE);
|
||||
return align(hdrSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaCertSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->certChainSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaTikOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 certOffset = GetCiaCertOffset(hdr);
|
||||
u64 certSize = GetCiaCertSize(hdr);
|
||||
return align(certOffset + certSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaTikSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->tikSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaTmdOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 tikOffset = GetCiaTikOffset(hdr);
|
||||
u64 tikSize = GetCiaTikSize(hdr);
|
||||
return align(tikOffset + tikSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaTmdSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->tmdSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaContentOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 tmdOffset = GetCiaTmdOffset(hdr);
|
||||
u64 tmdSize = GetCiaTmdSize(hdr);
|
||||
return align(tmdOffset + tmdSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaContentSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u64(hdr->contentSize,LE);
|
||||
}
|
||||
|
||||
u64 GetCiaMetaOffset(cia_hdr *hdr)
|
||||
{
|
||||
u64 contentOffset = GetCiaContentOffset(hdr);
|
||||
u64 contentSize = GetCiaContentSize(hdr);
|
||||
return align(contentOffset + contentSize,CIA_ALIGN_SIZE);
|
||||
}
|
||||
|
||||
u64 GetCiaMetaSize(cia_hdr *hdr)
|
||||
{
|
||||
return u8_to_u32(hdr->metaSize,LE);
|
||||
}
|
||||
|
||||
u8* GetCiaCert(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaCertOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaTik(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaTikOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaTmd(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaTmdOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaContent(u8 *cia)
|
||||
{
|
||||
return cia + GetCiaContentOffset((cia_hdr*)cia);
|
||||
}
|
||||
|
||||
u8* GetCiaMeta(u8 *cia)
|
||||
{
|
||||
if(GetCiaMetaSize((cia_hdr*)cia))
|
||||
return cia + GetCiaMetaOffset((cia_hdr*)cia);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user