コード例 #1
0
        public NintendoContentArchiveSource(NintendoContentFileSystemInfo fileSystemInfo, KeyConfiguration config, bool needsLogoPartition = false)
        {
            this.m_fileSystemInfo = fileSystemInfo;
            this.m_keyConfig      = config;
            this.SetCryptor(this.m_keyConfig);
            this.AddDefaultLogoPartitionIfNeeded(needsLogoPartition);
            fileSystemInfo.fsEntries.Sort((Comparison <NintendoContentFileSystemInfo.EntryInfo>)((x, y) => x.partitionIndex.CompareTo(y.partitionIndex)));
            NintendoContentFileSystemMeta meta = new NintendoContentFileSystemMeta();
            NintendoContentFileSystemEntryInfoContainer fsEntries = new NintendoContentFileSystemEntryInfoContainer(fileSystemInfo.fsEntries);
            List <ConcatenatedSource.Element>           elements1 = new List <ConcatenatedSource.Element>();

            NintendoContentArchiveSource.BodySourceElement[] bodySources = new NintendoContentArchiveSource.BodySourceElement[fileSystemInfo.fsEntries.Count];
            long offset = (long)meta.GetFsHeaderSize() * 4L;

            foreach (NintendoContentFileSystemInfo.EntryInfo entryInfo in fsEntries)
            {
                if (entryInfo.type != null)
                {
                    ISource source = NintendoContentArchiveSource.GetDataSource(entryInfo);
                    if (fileSystemInfo.isProdEncryption && fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 0)
                    {
                        source = this.AcidResignedSource(source);
                    }
                    if (fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 1)
                    {
                        source = this.NrrSignedSource(source);
                    }
                    int currentIndex = fsEntries.CurrentIndex;
                    bodySources[currentIndex].DataOffset = offset;
                    NintendoContentArchiveSource.BuildDataInfo buildInfo = new NintendoContentArchiveSource.BuildDataInfo(meta, source, offset, currentIndex);
                    fileSystemInfo.fsEntries[currentIndex] = this.BuildData(entryInfo, buildInfo);
                    offset = buildInfo.CurrentOffset;
                    Sha256HierarchicalHashCalculatedSource calculatedSource = new Sha256HierarchicalHashCalculatedSource(buildInfo.HeaderSource, (int)buildInfo.HeaderSource.Size, 1);
                    ConcatenatedSource.Element             element1         = new ConcatenatedSource.Element(calculatedSource.GetMasterHashSource(), "fsHeaderHash" + (object)currentIndex, (long)(32 * currentIndex));
                    elements1.Add(element1);
                    ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource)calculatedSource, "fsHeader" + (object)currentIndex, (long)currentIndex * (long)meta.GetFsHeaderSize());
                    bodySources[currentIndex].HeaderElement      = element2;
                    bodySources[currentIndex].DataSourceElements = buildInfo.DataSourceElements;
                }
            }
            if (fsEntries.IsReverse)
            {
                elements1.Reverse();
            }
            NintendoContentArchiveSource.BodyEncryptionKey bodyEncryptionKey = new NintendoContentArchiveSource.BodyEncryptionKey(fileSystemInfo);
            this.MakeBody(meta, fsEntries, bodySources, bodyEncryptionKey);
            this.MakeNcaHeader(meta, (ISource) new ConcatenatedSource(elements1), bodyEncryptionKey);
            List <ConcatenatedSource.Element> elements2 = new List <ConcatenatedSource.Element>();

            ConcatenatedSource.Element element3 = new ConcatenatedSource.Element(this.m_headerSource, "header", 0L);
            ConcatenatedSource.Element element4 = new ConcatenatedSource.Element(this.m_bodySource, "body", element3.Source.Size);
            elements2.Add(element3);
            elements2.Add(element4);
            this.m_source = (ISource) new ConcatenatedSource(elements2);
            this.Size     = this.m_source.Size;
        }
コード例 #2
0
        private void MakeNcaHeader(NintendoContentFileSystemMeta meta, ISource fsHeadersHashSource, NintendoContentArchiveSource.BodyEncryptionKey bodyEncryptionKey)
        {
            byte[] array = bodyEncryptionKey.ToArray();
            byte[] dst   = new byte[array.Length];
            this.m_bodyEncryptionKeyEncryptor.EncryptBlock(array, 0, array.Length, dst, 0);
            Buffer.BlockCopy((Array)dst, 0, (Array)this.m_fileSystemInfo.encryptedKey, 0, dst.Length);
            Rsa2048PssSha256SignedSource sha256SignedSource = new Rsa2048PssSha256SignedSource((ISource) new AdaptedSource((ISource) new MemorySource(meta.CreateNcaHeader(this.m_fileSystemInfo), 512, (int)((long)meta.GetHeaderSize() - 512L)), fsHeadersHashSource, 128L, fsHeadersHashSource.Size), this.m_header1Signer, this.m_header2Signer);

            this.m_headerSource = (ISource) new Aes128XtsEncryptedSource((ISource) new ConcatenatedSource(new List <ConcatenatedSource.Element>()
            {
                new ConcatenatedSource.Element(sha256SignedSource.GetSignatureValueSource(0), "headerSign1", 0L),
                new ConcatenatedSource.Element(sha256SignedSource.GetSignatureValueSource(1), "headerSign2", 256L),
                new ConcatenatedSource.Element((ISource)sha256SignedSource, "headerMain", 512L)
            }), this.m_headerEncryptor);
        }
コード例 #3
0
        private void MakeBody(NintendoContentFileSystemMeta meta, NintendoContentFileSystemEntryInfoContainer fsEntries, NintendoContentArchiveSource.BodySourceElement[] bodySources, NintendoContentArchiveSource.BodyEncryptionKey bodyEncryptionKey)
        {
            List <ConcatenatedSource.Element> elements = new List <ConcatenatedSource.Element>();

            for (int index = 0; index < bodySources.Length; ++index)
            {
                if (bodySources[index].HeaderElement == null)
                {
                    PaddingSource paddingSource = new PaddingSource((long)meta.GetFsHeaderSize());
                    elements.Add(new ConcatenatedSource.Element((ISource)paddingSource, "fsHeader" + (object)index, (long)index * (long)meta.GetFsHeaderSize()));
                }
                else
                {
                    ConcatenatedSource.Element headerElement = bodySources[index].HeaderElement;
                    ISource source = (ISource) new Aes128XtsEncryptedSource(headerElement.Source, this.m_headerEncryptor);
                    elements.Add(new ConcatenatedSource.Element(source, headerElement.Signature, headerElement.Offset));
                }
            }
            for (int length = bodySources.Length; length < 4; ++length)
            {
                PaddingSource paddingSource = new PaddingSource((long)meta.GetFsHeaderSize());
                elements.Add(new ConcatenatedSource.Element((ISource)paddingSource, "fsHeader" + (object)length, (long)length * (long)meta.GetFsHeaderSize()));
            }
            foreach (NintendoContentFileSystemInfo.EntryInfo fsEntry in fsEntries)
            {
                int     currentIndex = fsEntries.CurrentIndex;
                ISource source       = (ISource) new ConcatenatedSource(bodySources[currentIndex].DataSourceElements);
                switch (fsEntry.encryptionType)
                {
                case 1:
                    elements.Add(new ConcatenatedSource.Element(source, "fsData" + (object)currentIndex, bodySources[currentIndex].DataOffset));
                    continue;

                case 3:
                    source = (ISource) new Aes128CtrEncryptedSource(source, (ICtrModeEncryptor) new Aes128CtrCryptoDriver(bodyEncryptionKey.GetInternalKey(NintendoContentArchiveEncryptionKeyIndex.AesCtr)), (int)this.m_fileSystemInfo.keyGeneration, (long)fsEntry.startOffset);
                    goto case 1;

                default:
                    throw new InvalidDataException();
                }
            }
            this.m_bodySource = (ISource) new ConcatenatedSource(elements);
            this.m_fileSystemInfo.contentSize = meta.GetHeaderSize() + (ulong)this.m_bodySource.Size;
        }