public NCA3(BinaryReader br) { RSASig_0 = br.ReadBytes(0x100); RSASig_1 = br.ReadBytes(0x100); if ((Magic = new string(br.ReadChars(4))) != "NCA3") { throw new ApplicationException("Magic NCA3 not found!"); } IsGameCard = br.ReadBoolean(); ContentType = br.ReadByte(); CryptoType = br.ReadByte(); KeyIndex = br.ReadByte(); Size = br.ReadUInt64(); TitleID = br.ReadUInt64(); br.ReadBytes(4); //padding? SDKVersion = br.ReadUInt32(); CryptoType2 = br.ReadByte(); br.ReadBytes(15); //padding? RightsID = br.ReadBytes(0x10); List <SectionTableEntry> SectionTableEntries = new List <SectionTableEntry>(); for (var i = 0; i < 4; i++) { SectionTableEntries.Add(new SectionTableEntry(br)); } HashTable = new List <byte[]>(); for (var i = 0; i < 4; i++) { HashTable.Add(br.ReadBytes(0x20)); } var keyblob = new BinaryReader(new MemoryStream(AES.DecryptKeyArea(br, KeyIndex))); KeyArea = new List <byte[]>(); for (var i = 0; i < 4; i++) { KeyArea.Add(keyblob.ReadBytes(0x10)); } keyblob.Close(); //Section header block br.BaseStream.Position = 0x400; br.ReadBytes(3); //??? var fsType = br.ReadByte(); var cryptoType = br.ReadByte(); br.ReadBytes(3); //dont really need this stuff. Might finish later for completion UInt64 offsetRel = 0; UInt64 pfs0ActualSize = 0; if (fsType == 2) { //PFS0 superblock br.ReadBytes(0x38); offsetRel = br.ReadUInt64(); pfs0ActualSize = br.ReadUInt64(); } else if (fsType == 3) { //ROMFS superblock br.ReadBytes(0xE8); } br.BaseStream.Position = SectionTableEntries[0].MediaOffset; int contSize = (int)(SectionTableEntries[0].MediaEndOffset - SectionTableEntries[0].MediaOffset); byte[] iv = new byte[0x10]; Array.Copy(BitConverter.GetBytes(SectionTableEntries[0].MediaOffset >> 4), 0, iv, 0, 4); Array.Reverse(iv); var dec_cont = AES.CTRMode(br, contSize, KeyArea[cryptoType == 3 ? 2 : 0], iv); dec_cont.ReadBytes((int)offsetRel); pfs0 = new PFS0(dec_cont); }
public NCA3(string filename) : this(AES.DecryptHeader(File.ReadAllBytes(filename))) { }