Support NCA0 sections using IVFC hashes

This commit is contained in:
Alex Barney 2020-11-25 22:04:25 -07:00
parent a0487980d4
commit 7fcb0054e4
2 changed files with 21 additions and 10 deletions

View file

@ -315,15 +315,7 @@ namespace LibHac.FsSystem.NcaUtils
return rawStorage.Slice(0, header.GetPatchInfo().RelocationTreeOffset); return rawStorage.Slice(0, header.GetPatchInfo().RelocationTreeOffset);
} }
switch (header.HashType) return CreateVerificationStorage(integrityCheckLevel, header, rawStorage);
{
case NcaHashType.Sha256:
return InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel, true);
case NcaHashType.Ivfc:
return InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true);
default:
throw new ArgumentOutOfRangeException();
}
} }
public IStorage OpenStorageWithPatch(Nca patchNca, int index, IntegrityCheckLevel integrityCheckLevel) public IStorage OpenStorageWithPatch(Nca patchNca, int index, IntegrityCheckLevel integrityCheckLevel)
@ -331,11 +323,24 @@ namespace LibHac.FsSystem.NcaUtils
IStorage rawStorage = OpenRawStorageWithPatch(patchNca, index); IStorage rawStorage = OpenRawStorageWithPatch(patchNca, index);
NcaFsHeader header = patchNca.GetFsHeader(index); NcaFsHeader header = patchNca.GetFsHeader(index);
return CreateVerificationStorage(integrityCheckLevel, header, rawStorage);
}
private IStorage CreateVerificationStorage(IntegrityCheckLevel integrityCheckLevel, NcaFsHeader header,
IStorage rawStorage)
{
switch (header.HashType) switch (header.HashType)
{ {
case NcaHashType.Sha256: case NcaHashType.Sha256:
return InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel, true); return InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel,
true);
case NcaHashType.Ivfc: case NcaHashType.Ivfc:
// The FS header of an NCA0 section with IVFC verification must be manually skipped
if (Header.IsNca0())
{
rawStorage = rawStorage.Slice(0x200);
}
return InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true); return InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true);
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();

View file

@ -97,6 +97,12 @@ namespace LibHac.FsSystem.NcaUtils
IStorage storage = nca.OpenRawStorage(index); IStorage storage = nca.OpenRawStorage(index);
// The FS header of an NCA0 section with IVFC verification must be manually skipped
if (nca.Header.IsNca0() && header.HashType == NcaHashType.Ivfc)
{
offset += 0x200;
}
var data = new byte[size]; var data = new byte[size];
storage.Read(offset, data).ThrowIfFailure(); storage.Read(offset, data).ThrowIfFailure();