コード例 #1
0
        public IStorage OpenStorageWithPatch(Nca patchNca, int index, IntegrityCheckLevel integrityCheckLevel)
        {
            IStorage    rawStorage = OpenRawStorageWithPatch(patchNca, index);
            NcaFsHeader header     = patchNca.Header.GetFsHeader(index);

            switch (header.HashType)
            {
            case NcaHashType.Sha256:
                return(InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel, true));

            case NcaHashType.Ivfc:
                return(InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #2
0
ファイル: Nca.cs プロジェクト: garoxas/LibHac
        private IStorage CreateVerificationStorage(IntegrityCheckLevel integrityCheckLevel, NcaFsHeader header,
                                                   IStorage rawStorage)
        {
            switch (header.HashType)
            {
            case NcaHashType.Sha256:
                return(InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel,
                                              true));

            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));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #3
0
        public IStorage OpenStorage(int index, IntegrityCheckLevel integrityCheckLevel)
        {
            IStorage    rawStorage = OpenRawStorage(index);
            NcaFsHeader header     = Header.GetFsHeader(index);

            if (header.EncryptionType == NcaEncryptionType.AesCtrEx)
            {
                return(rawStorage.Slice(0, header.GetPatchInfo().RelocationTreeOffset));
            }

            switch (header.HashType)
            {
            case NcaHashType.Sha256:
                return(InitIvfcForPartitionFs(header.GetIntegrityInfoSha256(), rawStorage, integrityCheckLevel, true));

            case NcaHashType.Ivfc:
                return(InitIvfcForRomFs(header.GetIntegrityInfoIvfc(), rawStorage, integrityCheckLevel, true));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #4
0
        public static Validity ValidateSectionMasterHash(this Nca nca, int index)
        {
            if (!nca.SectionExists(index))
            {
                throw new ArgumentException(nameof(index), Messages.NcaSectionMissing);
            }
            if (!nca.CanOpenSection(index))
            {
                return(Validity.MissingKey);
            }

            NcaFsHeader header = nca.Header.GetFsHeader(index);

            // The base data is needed to validate the hash, so use a trick involving the AES-CTR extended
            // encryption table to check if the decryption is invalid.
            // todo: If the patch replaces the data checked by the master hash, use that directly
            if (header.IsPatchSection())
            {
                if (header.EncryptionType != NcaEncryptionType.AesCtrEx)
                {
                    return(Validity.Unchecked);
                }

                Validity ctrExValidity = ValidateCtrExDecryption(nca, index);
                return(ctrExValidity == Validity.Invalid ? Validity.Invalid : Validity.Unchecked);
            }

            byte[] expectedHash;
            long   offset;
            long   size;

            switch (header.HashType)
            {
            case NcaHashType.Ivfc:
                NcaFsIntegrityInfoIvfc ivfcInfo = header.GetIntegrityInfoIvfc();

                expectedHash = ivfcInfo.MasterHash.ToArray();
                offset       = ivfcInfo.GetLevelOffset(0);
                size         = 1 << ivfcInfo.GetLevelBlockSize(0);

                break;

            case NcaHashType.Sha256:
                NcaFsIntegrityInfoSha256 sha256Info = header.GetIntegrityInfoSha256();
                expectedHash = sha256Info.MasterHash.ToArray();

                offset = sha256Info.GetLevelOffset(0);
                size   = sha256Info.GetLevelSize(0);

                break;

            default:
                return(Validity.Unchecked);
            }

            IStorage storage = nca.OpenRawStorage(index);

            var data = new byte[size];

            storage.Read(offset, data).ThrowIfFailure();

            var actualHash = new byte[Sha256.DigestSize];

            Sha256.GenerateSha256Hash(data, actualHash);

            if (Utilities.ArraysEqual(expectedHash, actualHash))
            {
                return(Validity.Valid);
            }

            return(Validity.Invalid);
        }