Fixed: CFA crypto handling

This commit is contained in:
d0k3 2016-12-06 15:48:24 +01:00
parent d8442ac0cb
commit 8b0f4f2006
2 changed files with 38 additions and 30 deletions

View File

@ -45,7 +45,7 @@ u32 ValidateNcchHeader(NcchHeader* header) {
u32 GetNcchCtr(u8* ctr, NcchHeader* ncch, u8 section) {
memset(ctr, 0x00, 16);
if (ncch->version == 1) {
memcpy(ctr, &(ncch->programId), 8);
memcpy(ctr, &(ncch->partitionId), 8);
if (section == 1) { // ExtHeader ctr
add_ctr(ctr, NCCH_EXTHDR_OFFSET);
} else if (section == 2) { // ExeFS ctr
@ -55,7 +55,7 @@ u32 GetNcchCtr(u8* ctr, NcchHeader* ncch, u8 section) {
}
} else {
for (u32 i = 0; i < 8; i++)
ctr[i] = ((u8*) &(ncch->programId))[7-i];
ctr[i] = ((u8*) &(ncch->partitionId))[7-i];
ctr[8] = section;
}
@ -188,8 +188,7 @@ u32 SetNcchKey(NcchHeader* ncch, u32 keyid) {
}
u32 CheckNcchCrypto(NcchHeader* ncch) {
return (!NCCH_ENCRYPTED(ncch)) ? 1 :
((SetNcchKey(ncch, 0) == 0) && (SetNcchKey(ncch, 1) == 0)) ? 0 : 1;
return ((SetNcchKey(ncch, 0) == 0) && (SetNcchKey(ncch, 1) == 0)) ? 0 : 1;
}
u32 DecryptNcchSection(u8* data, u32 offset_data, u32 size_data,
@ -241,11 +240,15 @@ u32 DecryptNcch(u8* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* e
}
// exthdr handling
if (ncch->size_exthdr) {
if (DecryptNcchSection(data, offset, size,
NCCH_EXTHDR_OFFSET,
NCCH_EXTHDR_SIZE,
0, ncch, 1, 0) != 0) return 1;
}
// exefs handling
if (ncch->size_exefs) {
// exefs header handling
if (DecryptNcchSection(data, offset, size,
ncch->offset_exefs * NCCH_MEDIA_UNIT,
@ -259,12 +262,15 @@ u32 DecryptNcch(u8* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* e
file->size, 0x200 + file->offset,
ncch, 2, EXEFS_KEYID(file->name)) != 0) return 1;
}
}
// romfs handling
if (ncch->size_romfs) {
if (DecryptNcchSection(data, offset, size,
ncch->offset_romfs * NCCH_MEDIA_UNIT,
ncch->size_romfs * NCCH_MEDIA_UNIT,
0, ncch, 3, 1) != 0) return 1;
}
return 0;
}

View File

@ -393,12 +393,14 @@ bool OpenVGameDir(VirtualDir* vdir, VirtualFile* ventry) {
return false;
offset_ncch = vdir->offset;
if (!BuildVGameNcchDir()) return false;
if (ncch->size_exefs) {
u32 ncch_offset_exefs = offset_ncch + (ncch->offset_exefs * NCCH_MEDIA_UNIT);
if ((ReadNcchImageBytes((u8*) exefs, ncch_offset_exefs, sizeof(ExeFsHeader)) != 0) ||
(ValidateExeFsHeader(exefs, ncch->size_exefs * NCCH_MEDIA_UNIT) != 0))
return false;
offset_exefs = ncch_offset_exefs;
if (!BuildVGameExeFsDir()) return false;
}
} else if ((vdir->flags & VFLAG_EXEFS) && (offset_exefs != vdir->offset)) {
if ((ReadNcchImageBytes((u8*) exefs, vdir->offset, sizeof(ExeFsHeader)) != 0) ||
(ValidateExeFsHeader(exefs, ncch->size_exefs * NCCH_MEDIA_UNIT) != 0))