Example #1
0
        public ModifiableNintendoSubmissionPackageArchive(IReadableSink outSink, NintendoSubmissionPackageReader nspReader, ISource inSource, string targetEntryPath, string descFilePath, KeyConfiguration keyConfig)
        {
            this.m_KeyConfig = keyConfig;
            NintendoSubmissionPackageFileSystemInfo replacedNspInfo = ArchiveReconstructionUtils.GetReplacedNspInfo(nspReader, inSource, targetEntryPath, descFilePath, this.m_KeyConfig);

            this.ConnectionList = new List <Connection>((IEnumerable <Connection>) new NintendoSubmissionPackageArchive(outSink, replacedNspInfo, this.m_KeyConfig).ConnectionList);
        }
Example #2
0
        public ModifiableNintendoContentArchive(IReadableSink outSink, NintendoContentArchiveReader ncaReader, ISource inSource, string targetEntryPath, string descFilePath, KeyConfiguration keyConfig)
        {
            this.m_KeyConfig = keyConfig;
            NintendoContentArchiveSource contentArchiveSource = new NintendoContentArchiveSource(ArchiveReconstructionUtils.GetReplacedNcaInfo(ncaReader, descFilePath, new EntryReplaceRule()
            {
                Source = inSource,
                Path   = targetEntryPath
            }), this.m_KeyConfig, false);

            outSink.SetSize(contentArchiveSource.Size);
            this.ConnectionList = new List <Connection>();
            this.ConnectionList.Add(new Connection((ISource)contentArchiveSource, (ISink)outSink));
        }
        private static void CalculatePartitionSize(out long partitionHeaderSize, out long partitionSize, NintendoSubmissionPackageFileSystemInfo nspInfo, NintendoSubmissionPackageFileSystemInfo patchInfo, bool isNormal, KeyConfiguration keyConfig)
        {
            long          num           = 0;
            List <string> entryNameList = new List <string>();

            for (int index1 = 0; index1 < nspInfo.Entries.Count; ++index1)
            {
                List <Tuple <ISource, NintendoContentInfo> >      contentSourceList = new List <Tuple <ISource, NintendoContentInfo> >();
                NintendoSubmissionPackageFileSystemInfo.EntryInfo entry             = nspInfo.Entries[index1];
                for (int index2 = 0; index2 < entry.Contents.Count; ++index2)
                {
                    NintendoSubmissionPackageFileSystemInfo.ContentInfo content = entry.Contents[index2];
                    if ((!isNormal || !(content.ContentType != "Control")) && !(content.ContentType == "Meta"))
                    {
                        ISource source;
                        if (content.FsInfo != null)
                        {
                            source = (ISource) new NintendoContentArchiveSource(content.FsInfo as NintendoContentFileSystemInfo, keyConfig, false);
                        }
                        else
                        {
                            if (content.Source == null)
                            {
                                throw new NotImplementedException();
                            }
                            source = content.Source;
                        }
                        contentSourceList.Add(Tuple.Create <ISource, NintendoContentInfo>(source, new NintendoContentInfo(content.ContentType, source.Size)));
                        entryNameList.Add("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.nca");
                        num += ProdEncryptedXciArchive.RoundupPageSize(source.Size);
                    }
                }
                entryNameList.Add("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cnmt.nca");
                NintendoContentMetaArchiveSource metaArchiveSource = new NintendoContentMetaArchiveSource(entry.ContentMetaInfo == null ? new NintendoContentMetaBase(contentSourceList, entry.MetaType, entry.MetaFilePath) : new NintendoContentMetaBase(contentSourceList, entry.ContentMetaInfo.Data, entry.ContentMetaInfo.Model, true), entry.KeyIndex, keyConfig, nspInfo.IsProdEncryption, true);
                num += ProdEncryptedXciArchive.RoundupPageSize(metaArchiveSource.Size);
            }
            partitionHeaderSize = HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta> .GetDummySize(entryNameList);

            ProdEncryptedXciArchive.CheckAlignmentPageSize(partitionHeaderSize);
            partitionSize = num;
        }
        public ProdEncryptedXciArchive(IReadableSink outSink, NintendoSubmissionPackageReader nspReader, NintendoSubmissionPackageReader uppReader, NintendoSubmissionPackageReader patchReader, byte launchFlags, KeyConfiguration keyConfig)
        {
            this.ConnectionList = new List <Connection>();
            this.m_rng          = new RNGCryptoServiceProvider();
            this.m_keyConfig    = keyConfig;
            this.SetCryptor(this.m_keyConfig);
            uint  num1 = 0;
            uint  num2 = 0;
            ulong num3 = 0;

            byte[] numArray1 = (byte[])null;
            NintendoSubmissionPackageFileSystemInfo prodNspInfo = ArchiveReconstructionUtils.GetProdNspInfo(nspReader, this.m_keyConfig);

            XciUtils.CheckRomSizeAndClockRate(prodNspInfo.CardSize, prodNspInfo.CardClockRate);
            NintendoSubmissionPackageFileSystemInfo uppInfo = (NintendoSubmissionPackageFileSystemInfo)null;

            if (uppReader != null)
            {
                uppInfo = ArchiveReconstructionUtils.GetProdNspInfo(uppReader, this.m_keyConfig);
            }
            XciSizeInfo xciSize = ProdEncryptedXciArchive.CalculateXciSize(prodNspInfo, uppInfo, (NintendoSubmissionPackageFileSystemInfo)null, this.m_keyConfig);
            int         romSize = XciUtils.GetRomSize(xciSize.TotalSize);

            if (romSize == XciInfo.InvalidRomSize)
            {
                throw new ArgumentException(string.Format("Xci size exceed the maximum size of the game card.", Array.Empty <object>()));
            }
            if (prodNspInfo.CardSize < romSize)
            {
                throw new ArgumentException(string.Format("Xci requires CardSpec/Size = {0}, though it is set as {1}.", (object)romSize, (object)prodNspInfo.CardSize));
            }
            outSink.SetSize(xciSize.TotalSize);
            List <Sha256PartitionFsHashSource> hashSources1 = new List <Sha256PartitionFsHashSource>();
            PartitionFileSystemInfo            partFsInfo1  = new PartitionFileSystemInfo();
            List <ContentHashSource>           hashSources2 = new List <ContentHashSource>();
            List <Sha256PartitionFsHashSource> hashSources3 = new List <Sha256PartitionFsHashSource>();

            if (uppInfo != null && uppReader != null)
            {
                long partitionHeaderSize = xciSize.UpdatePartitionHeaderSize;
                foreach (NintendoSubmissionPackageFileSystemInfo.EntryInfo entry in uppInfo.Entries)
                {
                    if (entry.MetaType == "SystemUpdate")
                    {
                        NintendoContentMetaReader contentMetaReader = new NintendoContentMetaReader(entry.ContentMetaInfo.Data);
                        num2 = contentMetaReader.GetVersion();
                        num3 = contentMetaReader.GetId();
                    }
                }
                byte[] buffer = uppReader.ReadBase(0L, uppReader.GetBaseSize());
                numArray1 = new SHA256CryptoServiceProvider().ComputeHash(buffer, 0, buffer.Length);
                foreach (Tuple <string, long> tuple in uppReader.ListFileInfo().FindAll((Predicate <Tuple <string, long> >)(x => x.Item1.EndsWith(".nca"))))
                {
                    string str    = tuple.Item1;
                    long   num4   = tuple.Item2;
                    ulong  offset = (ulong)(partitionHeaderSize - xciSize.UpdatePartitionHeaderSize);
                    PartitionFileSystemInfo.EntryInfo entryInfo = PartitionFileSystemInfo.EntryInfo.Make(str, (ulong)num4, offset, 0UL, XciInfo.PageSize);
                    partFsInfo1.entries.Add(entryInfo);
                    FileSystemArchvieFileSource archvieFileSource = new FileSystemArchvieFileSource((IFileSystemArchiveReader)uppReader, str);
                    IReadableSink readableSink = (IReadableSink) new ReadableSubSink(outSink, xciSize.UpdatePartitionOffset + partitionHeaderSize, archvieFileSource.Size);
                    this.ConnectionList.Add(new Connection((ISource)archvieFileSource, (ISink)readableSink));
                    hashSources2.Add(new ContentHashSource((ISource)null, "no_change"));
                    SinkLinkedSource sinkLinkedSource = new SinkLinkedSource((ISink)readableSink, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink.ToSource(), 0L, (long)XciInfo.PageSize)));
                    hashSources3.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource, hashSources3.Count));
                    partitionHeaderSize += archvieFileSource.Size;
                }
            }
            HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource1 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources2, partFsInfo1, xciSize.UpdatePartitionHeaderSize), hashSources3);
            IReadableSink readableSink1 = (IReadableSink) new ReadableSubSink(outSink, xciSize.UpdatePartitionOffset, partitionFsHeaderSource1.Size);

            this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource1, (ISink)readableSink1));
            SinkLinkedSource sinkLinkedSource1 = new SinkLinkedSource((ISink)readableSink1, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink1.ToSource(), 0L, xciSize.UpdatePartitionHeaderSize)));

            hashSources1.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource1, hashSources1.Count));
            PartitionFileSystemInfo            partFsInfo2  = new PartitionFileSystemInfo();
            PartitionFileSystemInfo            partFsInfo3  = new PartitionFileSystemInfo();
            List <ContentHashSource>           hashSources4 = new List <ContentHashSource>();
            List <ContentHashSource>           hashSources5 = new List <ContentHashSource>();
            List <Sha256PartitionFsHashSource> hashSources6 = new List <Sha256PartitionFsHashSource>();
            List <Sha256PartitionFsHashSource> hashSources7 = new List <Sha256PartitionFsHashSource>();
            long partitionHeaderSize1 = xciSize.SecurePartitionHeaderSize;
            long partitionHeaderSize2 = xciSize.NormalPartitionHeaderSize;

            for (int index1 = 0; index1 < prodNspInfo.Entries.Count; ++index1)
            {
                NintendoSubmissionPackageFileSystemInfo.EntryInfo entry             = prodNspInfo.Entries[index1];
                List <Tuple <ISource, NintendoContentInfo> >      contentSourceList = new List <Tuple <ISource, NintendoContentInfo> >();
                for (int index2 = 0; index2 < entry.Contents.Count; ++index2)
                {
                    NintendoSubmissionPackageFileSystemInfo.ContentInfo content = entry.Contents[index2];
                    if (!(content.ContentType == "Meta"))
                    {
                        if (content.ContentType == "Program")
                        {
                            num1 = (content.FsInfo as NintendoContentFileSystemInfo).sdkAddonVersion;
                        }
                        (content.FsInfo as NintendoContentFileSystemInfo).distributionType = (byte)1;
                        NintendoContentArchiveSource contentArchiveSource = new NintendoContentArchiveSource(content.FsInfo as NintendoContentFileSystemInfo, this.m_keyConfig, false);
                        ulong offset1 = (ulong)(partitionHeaderSize1 - xciSize.SecurePartitionHeaderSize);
                        PartitionFileSystemInfo.EntryInfo entryInfo1 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.nca", (ulong)contentArchiveSource.Size, offset1, 0UL, XciInfo.PageSize);
                        partFsInfo2.entries.Add(entryInfo1);
                        IReadableSink readableSink2 = (IReadableSink) new ReadableSubSink(outSink, xciSize.SecurePartitionOffset + partitionHeaderSize1, contentArchiveSource.Size);
                        this.ConnectionList.Add(new Connection((ISource)contentArchiveSource, (ISink)readableSink2));
                        SinkLinkedSource sinkLinkedSource2 = new SinkLinkedSource((ISink)readableSink2, (ISource) new Sha256StreamHashSource(readableSink2.ToSource()));
                        SinkLinkedSource sinkLinkedSource3 = new SinkLinkedSource((ISink)readableSink2, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink2.ToSource(), 0L, (long)XciInfo.PageSize)));
                        hashSources4.Add(new ContentHashSource((ISource)sinkLinkedSource2, ".nca"));
                        hashSources6.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource3, hashSources6.Count));
                        contentSourceList.Add(Tuple.Create <ISource, NintendoContentInfo>(hashSources4[hashSources4.Count - 1].Source, new NintendoContentInfo(content.ContentType, contentArchiveSource.Size)));
                        partitionHeaderSize1 += ProdEncryptedXciArchive.RoundupPageSize(contentArchiveSource.Size);
                        if (content.ContentType == "Control")
                        {
                            ulong offset2 = (ulong)(partitionHeaderSize2 - xciSize.NormalPartitionHeaderSize);
                            PartitionFileSystemInfo.EntryInfo entryInfo2 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.nca", (ulong)contentArchiveSource.Size, offset2, 0UL, XciInfo.PageSize);
                            partFsInfo3.entries.Add(entryInfo2);
                            SinkLinkedSource sinkLinkedSource4 = new SinkLinkedSource((ISink)readableSink2, readableSink2.ToSource());
                            IReadableSink    readableSink3     = (IReadableSink) new ReadableSubSink(outSink, xciSize.NormalPartitionOffset + partitionHeaderSize2, sinkLinkedSource4.Size);
                            this.ConnectionList.Add(new Connection((ISource)sinkLinkedSource4, (ISink)readableSink3));
                            hashSources5.Add(new ContentHashSource((ISource)sinkLinkedSource2, ".nca"));
                            hashSources7.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource3, hashSources7.Count));
                            partitionHeaderSize2 += ProdEncryptedXciArchive.RoundupPageSize(contentArchiveSource.Size);
                        }
                    }
                }
                NintendoContentMetaArchiveSource metaArchiveSource = new NintendoContentMetaArchiveSource(new NintendoContentMetaBase(contentSourceList, entry.ContentMetaInfo.Data, entry.ContentMetaInfo.Model, true), entry.KeyIndex, this.m_keyConfig, prodNspInfo.IsProdEncryption, true);
                ulong offset3 = (ulong)(partitionHeaderSize1 - xciSize.SecurePartitionHeaderSize);
                PartitionFileSystemInfo.EntryInfo entryInfo3 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cnmt.nca", (ulong)metaArchiveSource.Size, offset3, 0UL, XciInfo.PageSize);
                partFsInfo2.entries.Add(entryInfo3);
                IReadableSink readableSink4 = (IReadableSink) new ReadableSubSink(outSink, xciSize.SecurePartitionOffset + partitionHeaderSize1, metaArchiveSource.Size);
                this.ConnectionList.Add(new Connection((ISource)metaArchiveSource, (ISink)readableSink4));
                SinkLinkedSource sinkLinkedSource5 = new SinkLinkedSource((ISink)readableSink4, (ISource) new Sha256StreamHashSource(readableSink4.ToSource()));
                SinkLinkedSource sinkLinkedSource6 = new SinkLinkedSource((ISink)readableSink4, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink4.ToSource(), 0L, (long)XciInfo.PageSize)));
                hashSources4.Add(new ContentHashSource((ISource)sinkLinkedSource5, ".cnmt.nca"));
                hashSources6.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource6, hashSources6.Count));
                partitionHeaderSize1 += ProdEncryptedXciArchive.RoundupPageSize(metaArchiveSource.Size);
                ulong offset4 = (ulong)(partitionHeaderSize2 - xciSize.NormalPartitionHeaderSize);
                PartitionFileSystemInfo.EntryInfo entryInfo4 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cnmt.nca", (ulong)metaArchiveSource.Size, offset4, 0UL, XciInfo.PageSize);
                partFsInfo3.entries.Add(entryInfo4);
                SinkLinkedSource sinkLinkedSource7 = new SinkLinkedSource((ISink)readableSink4, readableSink4.ToSource());
                IReadableSink    readableSink5     = (IReadableSink) new ReadableSubSink(outSink, xciSize.NormalPartitionOffset + partitionHeaderSize2, sinkLinkedSource7.Size);
                this.ConnectionList.Add(new Connection((ISource)sinkLinkedSource7, (ISink)readableSink5));
                hashSources5.Add(new ContentHashSource((ISource)sinkLinkedSource5, ".cnmt.nca"));
                hashSources7.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource6, hashSources7.Count));
                partitionHeaderSize2 += ProdEncryptedXciArchive.RoundupPageSize(metaArchiveSource.Size);
            }
            HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource2 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources5, partFsInfo3, xciSize.NormalPartitionHeaderSize), hashSources7);
            IReadableSink readableSink6 = (IReadableSink) new ReadableSubSink(outSink, xciSize.NormalPartitionOffset, partitionFsHeaderSource2.Size);

            this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource2, (ISink)readableSink6));
            SinkLinkedSource sinkLinkedSource8 = new SinkLinkedSource((ISink)readableSink6, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink6.ToSource(), 0L, xciSize.NormalPartitionHeaderSize)));

            hashSources1.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource8, hashSources1.Count));
            HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource3 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources4, partFsInfo2, xciSize.SecurePartitionHeaderSize), hashSources6);
            IReadableSink readableSink7 = (IReadableSink) new ReadableSubSink(outSink, xciSize.SecurePartitionOffset, partitionFsHeaderSource3.Size);

            this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource3, (ISink)readableSink7));
            SinkLinkedSource sinkLinkedSource9 = new SinkLinkedSource((ISink)readableSink7, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink7.ToSource(), 0L, xciSize.SecurePartitionHeaderSize)));

            hashSources1.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource9, hashSources1.Count));
            PartitionFileSystemInfo  partFsInfo4  = new PartitionFileSystemInfo();
            List <ContentHashSource> hashSources8 = new List <ContentHashSource>();
            ulong offset5 = (ulong)(xciSize.UpdatePartitionOffset - xciSize.UpdatePartitionOffset);

            PartitionFileSystemInfo.EntryInfo entryInfo5 = PartitionFileSystemInfo.EntryInfo.Make("update", (ulong)(xciSize.UpdatePartitionHeaderSize + xciSize.UpdatePartitionSize), offset5, 0UL, (uint)xciSize.UpdatePartitionHeaderSize);
            partFsInfo4.entries.Add(entryInfo5);
            hashSources8.Add(new ContentHashSource((ISource)null, "update"));
            ulong offset6 = (ulong)(xciSize.NormalPartitionOffset - xciSize.UpdatePartitionOffset);

            PartitionFileSystemInfo.EntryInfo entryInfo6 = PartitionFileSystemInfo.EntryInfo.Make("normal", (ulong)(xciSize.NormalPartitionHeaderSize + xciSize.NormalPartitionSize), offset6, 0UL, (uint)xciSize.NormalPartitionHeaderSize);
            partFsInfo4.entries.Add(entryInfo6);
            hashSources8.Add(new ContentHashSource((ISource)null, "normal"));
            ulong offset7 = (ulong)(xciSize.SecurePartitionOffset - xciSize.UpdatePartitionOffset);

            PartitionFileSystemInfo.EntryInfo entryInfo7 = PartitionFileSystemInfo.EntryInfo.Make("secure", (ulong)(xciSize.SecurePartitionHeaderSize + xciSize.SecurePartitionSize), offset7, 0UL, (uint)xciSize.SecurePartitionHeaderSize);
            partFsInfo4.entries.Add(entryInfo7);
            hashSources8.Add(new ContentHashSource((ISource)null, "secure"));
            HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource4 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources8, partFsInfo4, xciSize.RootPartitionHeaderSize), hashSources1);
            IReadableSink readableSink8 = (IReadableSink) new ReadableSubSink(outSink, xciSize.RootPartitionOffset, partitionFsHeaderSource4.Size);

            this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource4, (ISink)readableSink8));
            ISource rootPartitionFsHeaderHashSource = (ISource) new SinkLinkedSource((ISink)readableSink8, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink8.ToSource(), 0L, xciSize.RootPartitionHeaderSize)));

            byte[] data1 = new byte[8];
            this.m_rng.GetBytes(data1);
            ulong uint64 = BitConverter.ToUInt64(data1, 0);

            byte[] numArray2 = new byte[XciMeta.TitleKey1Size];
            byte[] numArray3 = new byte[XciMeta.TitleKey2Size];
            this.m_rng.GetBytes(numArray2);
            this.m_rng.GetBytes(numArray3);
            byte[]       initialData  = this.CreateInitialData(uint64, new Pair <byte[], byte[]>(numArray2, numArray3));
            byte[]       keyArea      = this.CreateKeyArea(initialData, new Pair <byte[], byte[]>(numArray2, numArray3));
            MemorySource memorySource = new MemorySource(keyArea, 0, keyArea.Length);

            byte[] data2 = new byte[XciInfo.IvSize];
            this.m_rng.GetBytes(data2);
            XciInfo xciInfo = new XciInfo();

            xciInfo.romAreaStartPageAddress = (uint)((ulong)xciSize.SecurePartitionOffset / (ulong)XciInfo.PageSize) - XciInfo.CardKeyAreaPageCount;
            xciInfo.kekIndex            = XciInfo.KekIndexVersion0;
            xciInfo.romSize             = XciInfo.ConvertRomSizeToRomSizeByte(prodNspInfo.CardSize);
            xciInfo.flags               = launchFlags;
            xciInfo.packageId           = uint64;
            xciInfo.validDataEndAddress = (uint)((int)(uint)((ulong)ProdEncryptedXciArchive.RoundupPageSize(xciSize.TotalSize) / (ulong)XciInfo.PageSize) - (int)XciInfo.CardKeyAreaPageCount - 1);
            xciInfo.iv = data2;
            xciInfo.partitionFsHeaderAddress = (ulong)(XciInfo.NormalAreaStartPageAddress - XciInfo.CardKeyAreaPageCount) * (ulong)XciInfo.PageSize;
            xciInfo.partitionFsHeaderSize    = (ulong)xciSize.RootPartitionHeaderSize;
            xciInfo.partitionFsHeaderHash    = (byte[])null;
            xciInfo.selSec     = XciInfo.SelSecForT1;
            xciInfo.fwVersion  = XciInfo.FwVersion;
            xciInfo.accCtrl1   = XciInfo.ConvertClockRateToAccCtrl1(prodNspInfo.CardClockRate);
            xciInfo.fwMode     = num1;
            xciInfo.cupVersion = num2;
            xciInfo.cupId      = num3;
            xciInfo.uppHash    = numArray1 != null ? ((IEnumerable <byte>)numArray1).Take <byte>(XciInfo.UppHashSize).ToArray <byte>() : new byte[XciInfo.UppHashSize];
            XciMeta         xciMeta          = new XciMeta(initialData);
            XciHeaderSource xciHeaderSource  = new XciHeaderSource(ref xciInfo, xciMeta, rootPartitionFsHeaderHashSource, this.m_headerEncryptor, this.m_headerSigner);
            ReadableSubSink readableSubSink1 = new ReadableSubSink(outSink, 0L, memorySource.Size);

            this.ConnectionList.Add(new Connection((ISource)memorySource, (ISink)readableSubSink1));
            ReadableSubSink readableSubSink2 = new ReadableSubSink(outSink, memorySource.Size, xciHeaderSource.Size);

            this.ConnectionList.Add(new Connection((ISource)xciHeaderSource, (ISink)readableSubSink2));
        }
        internal static XciSizeInfo CalculateXciSize(NintendoSubmissionPackageFileSystemInfo nspInfo, NintendoSubmissionPackageFileSystemInfo uppInfo, NintendoSubmissionPackageFileSystemInfo patchInfo, KeyConfiguration keyConfig)
        {
            XciSizeInfo xciSizeInfo = new XciSizeInfo();

            xciSizeInfo.RootPartitionOffset = (long)XciInfo.NormalAreaStartPageAddress * (long)XciInfo.PageSize;
            ProdEncryptedXciArchive.CalculateRootPartitionHeaderSize(out xciSizeInfo.RootPartitionHeaderSize);
            xciSizeInfo.UpdatePartitionOffset = xciSizeInfo.RootPartitionOffset + xciSizeInfo.RootPartitionHeaderSize;
            ProdEncryptedXciArchive.CalculateUpdatePartitionSize(out xciSizeInfo.UpdatePartitionHeaderSize, out xciSizeInfo.UpdatePartitionSize, uppInfo);
            xciSizeInfo.NormalPartitionOffset = xciSizeInfo.UpdatePartitionOffset + xciSizeInfo.UpdatePartitionHeaderSize + xciSizeInfo.UpdatePartitionSize;
            ProdEncryptedXciArchive.CalculatePartitionSize(out xciSizeInfo.NormalPartitionHeaderSize, out xciSizeInfo.NormalPartitionSize, nspInfo, patchInfo, true, keyConfig);
            xciSizeInfo.SecurePartitionOffset = ProdEncryptedXciArchive.RoundupRomAreaStartPageAddress(xciSizeInfo.NormalPartitionOffset + xciSizeInfo.NormalPartitionHeaderSize + xciSizeInfo.NormalPartitionSize) + (long)(XciInfo.CardKeyAreaPageCount * XciInfo.PageSize);
            ProdEncryptedXciArchive.CalculatePartitionSize(out xciSizeInfo.SecurePartitionHeaderSize, out xciSizeInfo.SecurePartitionSize, nspInfo, patchInfo, false, keyConfig);
            xciSizeInfo.TotalSize = xciSizeInfo.SecurePartitionOffset + xciSizeInfo.SecurePartitionHeaderSize + xciSizeInfo.SecurePartitionSize;
            return(xciSizeInfo);
        }
Example #6
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;
        }
Example #7
0
 private void SetCryptor(KeyConfiguration config)
 {
     if (this.m_fileSystemInfo.isProdEncryption)
     {
         this.m_bodyEncryptionKeyEncryptor = this.m_keyConfig.GetProdKeyAreaEncryptionKey() == null ? (IEncryptor) new HsmAes128CryptoDriver(Aes128KeyIndex.NcaContentKey) : (IEncryptor) new Aes128CryptoDriver(this.m_keyConfig.GetProdKeyAreaEncryptionKey().Key);
         byte[][] numArray1 = new byte[2][]
         {
             new byte[16],
             new byte[16]
         };
         byte[][] numArray2 = new byte[2][]
         {
             new byte[16]
             {
                 (byte)90,
                 (byte)62,
                 (byte)216,
                 (byte)79,
                 (byte)222,
                 (byte)192,
                 (byte)216,
                 (byte)38,
                 (byte)49,
                 (byte)247,
                 (byte)226,
                 (byte)93,
                 (byte)25,
                 (byte)123,
                 (byte)245,
                 (byte)208
             },
             new byte[16]
             {
                 (byte)28,
                 (byte)155,
                 (byte)123,
                 (byte)250,
                 (byte)246,
                 (byte)40,
                 (byte)24,
                 (byte)61,
                 (byte)113,
                 (byte)246,
                 (byte)77,
                 (byte)115,
                 (byte)241,
                 (byte)80,
                 (byte)185,
                 (byte)210
             }
         };
         IEncryptor encryptor = this.m_keyConfig.GetProdNcaHeaderEncryptionKek() == null ? (IEncryptor) new HsmAes128CryptoDriver(Aes128KeyIndex.NcaHeader) : (IEncryptor) new Aes128CryptoDriver(this.m_keyConfig.GetProdNcaHeaderEncryptionKek().Key);
         encryptor.DecryptBlock(numArray2[0], 0, 16, numArray1[0], 0);
         encryptor.DecryptBlock(numArray2[1], 0, 16, numArray1[1], 0);
         this.m_headerEncryptor = (IXtsModeEncryptor) new Aes128XtsCryptoDriver(numArray1[0], numArray1[1]);
         if (this.m_keyConfig.GetNcaHeader1SignKey() != null)
         {
             RsaKey ncaHeader1SignKey = this.m_keyConfig.GetNcaHeader1SignKey();
             this.m_header1Signer = (ISigner) new Rsa2048PssSha256SignCryptoDriver(ncaHeader1SignKey.KeyModulus, ncaHeader1SignKey.KeyPublicExponent, ncaHeader1SignKey.KeyPrivateExponent);
         }
         else
         {
             this.m_header1Signer = (ISigner) new HsmRsa2048PssSha256SignCryptoDriver(Rsa2048PssSha256KeyIndex.NcaHeader1);
         }
         if (this.m_fileSystemInfo.contentType != (byte)0)
         {
             this.m_header2Signer = (ISigner)null;
         }
         else
         {
             RsaKey randomRsaKey = this.m_keyConfig.GetRandomRsaKey();
             this.m_header2Signer = (ISigner) new Rsa2048PssSha256SignCryptoDriver(randomRsaKey.KeyModulus, randomRsaKey.KeyPublicExponent, randomRsaKey.KeyPrivateExponent);
         }
         if (this.m_keyConfig.GetAcidSignKey() != null)
         {
             RsaKey acidSignKey = this.m_keyConfig.GetAcidSignKey();
             this.m_acidSigner = (ISigner) new Rsa2048PssSha256SignCryptoDriver(acidSignKey.KeyModulus, acidSignKey.KeyPublicExponent, acidSignKey.KeyPrivateExponent);
         }
         else
         {
             this.m_acidSigner = (ISigner) new HsmRsa2048PssSha256SignCryptoDriver(Rsa2048PssSha256KeyIndex.Acid);
         }
         RsaKey randomRsaKey1 = this.m_keyConfig.GetRandomRsaKey();
         this.m_nrrSigner = (ISigner) new Rsa2048PssSha256SignCryptoDriver(randomRsaKey1.KeyModulus, randomRsaKey1.KeyPublicExponent, randomRsaKey1.KeyPrivateExponent);
         if (this.m_keyConfig.GetNrrCertificateSignKey() != null)
         {
             RsaKey certificateSignKey = this.m_keyConfig.GetNrrCertificateSignKey();
             this.m_nrrCertificateSigner = (ISigner) new Rsa2048PssSha256SignCryptoDriver(certificateSignKey.KeyModulus, certificateSignKey.KeyPublicExponent, certificateSignKey.KeyPrivateExponent);
         }
         else
         {
             this.m_nrrCertificateSigner = (ISigner) new HsmRsa2048PssSha256SignCryptoDriver(Rsa2048PssSha256KeyIndex.NrrCertificate);
         }
     }
     else
     {
         this.m_bodyEncryptionKeyEncryptor = (IEncryptor) new Aes128CryptoDriver(this.m_keyConfig.GetKeyAreaEncryptionKey((uint)this.m_fileSystemInfo.keyAreaEncryptionKeyIndex).Key);
         this.m_headerEncryptor            = (IXtsModeEncryptor) new Aes128XtsCryptoDriver(Aes128XtsCryptoDriver.GetDefaultKey(2), Aes128XtsCryptoDriver.GetDefaultKey(3));
         this.m_header1Signer        = (ISigner) new Rsa2048PssSha256SignCryptoDriver(Rsa2048PssSha256KeyIndex.NcaHeader1);
         this.m_header2Signer        = this.m_fileSystemInfo.contentType != (byte)0 || this.m_fileSystemInfo.header2SignKeyModulus == null || (this.m_fileSystemInfo.header2SignKeyPublicExponent == null || this.m_fileSystemInfo.header2SignKeyPrivateExponent == null) ? (ISigner)null : (ISigner) new Rsa2048PssSha256SignCryptoDriver(this.m_fileSystemInfo.header2SignKeyModulus, this.m_fileSystemInfo.header2SignKeyPublicExponent, this.m_fileSystemInfo.header2SignKeyPrivateExponent);
         this.m_acidSigner           = (ISigner)null;
         this.m_nrrSigner            = (ISigner) new Rsa2048PssSha256SignCryptoDriver(Rsa2048PssSha256KeyIndex.NrrCertificate);
         this.m_nrrCertificateSigner = (ISigner) new Rsa2048PssSha256SignCryptoDriver(Rsa2048PssSha256KeyIndex.NrrCertificate);
     }
 }