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

View File

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