public XciHeader(KeySet keySet, Stream stream) { using (var reader = new BinaryReader(stream, Encoding.Default, true)) { Signature = reader.ReadBytes(SignatureSize); Magic = reader.ReadAscii(4); if (Magic != HeaderMagic) { throw new InvalidDataException("Invalid XCI file: Header magic invalid."); } reader.BaseStream.Position = SignatureSize; byte[] sigData = reader.ReadBytes(SignatureSize); reader.BaseStream.Position = SignatureSize + 4; SignatureValidity = CryptoOld.Rsa2048Pkcs1Verify(sigData, Signature, _xciHeaderPubk); RomAreaStartPage = reader.ReadInt32(); BackupAreaStartPage = reader.ReadInt32(); byte keyIndex = reader.ReadByte(); KekIndex = (byte)(keyIndex >> 4); TitleKeyDecIndex = (byte)(keyIndex & 7); GameCardSize = (GameCardSizeInternal)reader.ReadByte(); CardHeaderVersion = reader.ReadByte(); Flags = (GameCardAttribute)reader.ReadByte(); PackageId = reader.ReadUInt64(); ValidDataEndPage = reader.ReadInt64(); AesCbcIv = reader.ReadBytes(Aes.KeySize128); Array.Reverse(AesCbcIv); RootPartitionOffset = reader.ReadInt64(); RootPartitionHeaderSize = reader.ReadInt64(); RootPartitionHeaderHash = reader.ReadBytes(Sha256.DigestSize); InitialDataHash = reader.ReadBytes(Sha256.DigestSize); SelSec = reader.ReadInt32(); SelT1Key = reader.ReadInt32(); SelKey = reader.ReadInt32(); LimAreaPage = reader.ReadInt32(); if (keySet != null && !keySet.XciHeaderKey.IsZeros()) { byte[] encHeader = reader.ReadBytes(EncryptedHeaderSize); byte[] decHeader = new byte[EncryptedHeaderSize]; Aes.DecryptCbc128(encHeader, decHeader, keySet.XciHeaderKey, AesCbcIv); using (var decReader = new BinaryReader(new MemoryStream(decHeader))) { FwVersion = decReader.ReadUInt64(); AccCtrl1 = (CardClockRate)decReader.ReadInt32(); Wait1TimeRead = decReader.ReadInt32(); Wait2TimeRead = decReader.ReadInt32(); Wait1TimeWrite = decReader.ReadInt32(); Wait2TimeWrite = decReader.ReadInt32(); FwMode = decReader.ReadInt32(); UppVersion = decReader.ReadInt32(); decReader.BaseStream.Position += 4; UppHash = decReader.ReadBytes(8); UppId = decReader.ReadUInt64(); } } ImageHash = new byte[Sha256.DigestSize]; Sha256.GenerateSha256Hash(sigData, ImageHash); reader.BaseStream.Position = RootPartitionOffset; byte[] headerBytes = reader.ReadBytes((int)RootPartitionHeaderSize); Span <byte> actualHeaderHash = stackalloc byte[Sha256.DigestSize]; Sha256.GenerateSha256Hash(headerBytes, actualHeaderHash); PartitionFsHeaderValidity = Utilities.SpansEqual(RootPartitionHeaderHash, actualHeaderHash) ? Validity.Valid : Validity.Invalid; } }