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