diff --git a/BurnOutSharp.Models/N3DS/ARM11KernelCapabilities.cs b/BurnOutSharp.Models/N3DS/ARM11KernelCapabilities.cs
new file mode 100644
index 00000000..94d03774
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ARM11KernelCapabilities.cs
@@ -0,0 +1,43 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// The kernel capability descriptors are passed to svcCreateProcess.
+ ///
+ ///
+ public sealed class ARM11KernelCapabilities
+ {
+ ///
+ /// Descriptors
+ /// -------------------
+ /// Pattern of bits 20-31 Type Fields
+ /// 0b1110xxxxxxxx Interrupt info
+ /// 0b11110xxxxxxx System call mask Bits 24-26: System call mask table index; Bits 0-23: mask
+ /// 0b1111110xxxxx Kernel release version Bits 8-15: Major version; Bits 0-7: Minor version
+ /// 0b11111110xxxx Handle table size Bits 0-18: size
+ /// 0b111111110xxx Kernel flags
+ /// 0b11111111100x Map address range Describes a memory mapping like the 0b111111111110 descriptor, but an entire range rather than a single page is mapped.Another 0b11111111100x descriptor must follow this one to denote the(exclusive) end of the address range to map.
+ /// 0b111111111110 Map memory page Bits 0-19: page index to map(virtual address >> 12; the physical address is determined per-page according to Memory layout); Bit 20: Map read-only(otherwise read-write)
+ ///
+ /// ARM11 Kernel Flags
+ /// -------------------
+ /// Bit Description
+ /// 0 Allow debug
+ /// 1 Force debug
+ /// 2 Allow non-alphanum
+ /// 3 Shared page writing
+ /// 4 Privilege priority
+ /// 5 Allow main() args
+ /// 6 Shared device memory
+ /// 7 Runnable on sleep
+ /// 8-11 Memory type(1: application, 2: system, 3: base)
+ /// 12 Special memory
+ /// 13 Process has access to CPU core 2 (New3DS only)
+ ///
+ public byte[][] Descriptors;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/ARM11LocalSystemCapabilities.cs b/BurnOutSharp.Models/N3DS/ARM11LocalSystemCapabilities.cs
new file mode 100644
index 00000000..0d21a859
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ARM11LocalSystemCapabilities.cs
@@ -0,0 +1,66 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class ARM11LocalSystemCapabilities
+ {
+ ///
+ /// Program ID
+ ///
+ public byte[] ProgramID;
+
+ ///
+ /// Core version (The Title ID low of the required FIRM)
+ ///
+ public uint CoreVersion;
+
+ ///
+ /// Flag1 (implemented starting from 8.0.0-18).
+ ///
+ public ARM11LSCFlag1 Flag1;
+
+ ///
+ /// Flag2 (implemented starting from 8.0.0-18).
+ ///
+ public ARM11LSCFlag2 Flag2;
+
+ ///
+ /// Flag0
+ ///
+ public ARM11LSCFlag0 Flag0;
+
+ ///
+ /// Priority
+ ///
+ public byte Priority;
+
+ ///
+ /// Resource limit descriptors. The first byte here controls the maximum allowed CpuTime.
+ ///
+ public byte[][] ResourceLimitDescriptors;
+
+ ///
+ /// Storage info
+ ///
+ public StorageInfo StorageInfo;
+
+ ///
+ /// Service access control
+ ///
+ public byte[][] ServiceAccessControl;
+
+ ///
+ /// Extended service access control, support for this was implemented with 9.3.0-X.
+ ///
+ public byte[][] ExtendedServiceAccessControl;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved;
+
+ ///
+ /// Resource limit category. (0 = APPLICATION, 1 = SYS_APPLET, 2 = LIB_APPLET, 3 = OTHER (sysmodules running under the BASE memregion))
+ ///
+ public ResourceLimitCategory ResourceLimitCategory;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/ARM9AccessControl.cs b/BurnOutSharp.Models/N3DS/ARM9AccessControl.cs
new file mode 100644
index 00000000..9bb45594
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ARM9AccessControl.cs
@@ -0,0 +1,17 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class ARM9AccessControl
+ {
+ ///
+ /// Descriptors
+ ///
+ public ARM9AccessControlDescriptors[] Descriptors;
+
+ ///
+ /// ARM9 Descriptor Version. Originally this value had to be ≥ 2.
+ /// Starting with 9.3.0-X this value has to be either value 2 or value 3.
+ ///
+ public byte DescriptorVersion;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/AccessControlInfo.cs b/BurnOutSharp.Models/N3DS/AccessControlInfo.cs
new file mode 100644
index 00000000..26afc8bc
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/AccessControlInfo.cs
@@ -0,0 +1,21 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class AccessControlInfo
+ {
+ ///
+ /// ARM11 local system capabilities
+ ///
+ public ARM11LocalSystemCapabilities ARM11LocalSystemCapabilities;
+
+ ///
+ /// ARM11 kernel capabilities
+ ///
+ public ARM11KernelCapabilities ARM11KernelCapabilities;
+
+ ///
+ /// ARM9 access control
+ ///
+ public ARM9AccessControl ARM9AccessControl;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/CIAHeader.cs b/BurnOutSharp.Models/N3DS/CIAHeader.cs
new file mode 100644
index 00000000..aec997ad
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/CIAHeader.cs
@@ -0,0 +1,94 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// CIA stands for CTR Importable Archive. This format allows the installation of
+ /// titles to the 3DS. CIA files and titles on Nintendo's CDN contain identical data.
+ /// As a consequence, valid CIA files can be generated from CDN content. This also
+ /// means CIA files can contain anything that titles on Nintendo's CDN can contain.
+ ///
+ /// Under normal circumstances CIA files are used where downloading a title is
+ /// impractical or not possible. Such as distributing a Download Play child, or
+ /// installing forced Gamecard updates. Those CIA(s) are stored by the titles in
+ /// question, in an auxiliary CFA file.
+ ///
+ ///
+ public sealed class CIAHeader
+ {
+ ///
+ /// Archive header size, usually 0x2020 bytes
+ ///
+ public int HeaderSize;
+
+ ///
+ /// Type
+ ///
+ public ushort Type;
+
+ ///
+ /// Version
+ ///
+ public ushort Version;
+
+ ///
+ /// Certificate chain size
+ ///
+ public int CertificateChainSize;
+
+ ///
+ /// Ticket size
+ ///
+ public int TicketSize;
+
+ ///
+ /// TMD file size
+ ///
+ public int TMDFileSize;
+
+ ///
+ /// Meta size (0 if no Meta data is present)
+ ///
+ public int MetaSize;
+
+ ///
+ /// Content size
+ ///
+ public long ContentSize;
+
+ ///
+ /// Content Index
+ ///
+ public byte[] ContentIndex;
+
+ #region Content Index
+
+ ///
+ /// Certificate chain
+ ///
+ ///
+ /// https://www.3dbrew.org/wiki/CIA#Certificate_Chain
+ ///
+ public Certificate[] CertificateChain;
+
+ ///
+ /// Ticket
+ ///
+ public Ticket Ticket;
+
+ ///
+ /// TMD file data
+ ///
+ public TitleMetadata TMDFileData;
+
+ ///
+ /// Content file data
+ ///
+ public NCCHHeader[] Partitions;
+
+ ///
+ /// Meta file data (Not a necessary component)
+ ///
+ public MetaFile MetaFileData;
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp.Models/N3DS/CXIExtendedHeader.cs b/BurnOutSharp.Models/N3DS/CXIExtendedHeader.cs
new file mode 100644
index 00000000..93a18121
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/CXIExtendedHeader.cs
@@ -0,0 +1,36 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// The exheader has two sections:
+ /// - The actual exheader data, containing System Control Info (SCI) and Access Control Info (ACI);
+ /// - A signed copy of NCCH HDR public key, and exheader ACI. This version of the ACI is used as limitation to the actual ACI.
+ ///
+ ///
+ public sealed class CXIExtendedHeader
+ {
+ ///
+ /// SCI
+ ///
+ public SystemControlInfo SCI;
+
+ ///
+ /// ACI
+ ///
+ public AccessControlInfo ACI;
+
+ ///
+ /// AccessDesc signature (RSA-2048-SHA256)
+ ///
+ public byte[] AccessDescSignature;
+
+ ///
+ /// NCCH HDR RSA-2048 public key
+ ///
+ public byte[] NCCHHDRPublicKey;
+
+ ///
+ /// ACI (for limitation of first ACI)
+ ///
+ public AccessControlInfo ACIForLimitations;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/Certificate.cs b/BurnOutSharp.Models/N3DS/Certificate.cs
new file mode 100644
index 00000000..83a31c48
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/Certificate.cs
@@ -0,0 +1,77 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// Certificates contain cryptography information for verifying Signatures.
+ /// These certificates are also signed. The parent/child relationship between
+ /// certificates, makes all the certificates effectively signed by 'Root',
+ /// the public key for which is stored in NATIVE_FIRM.
+ ///
+ ///
+ public sealed class Certificate
+ {
+ ///
+ /// Signature Type
+ ///
+ public SignatureType SignatureType;
+
+ ///
+ /// Signature size
+ ///
+ public ushort SignatureSize;
+
+ ///
+ /// Padding size
+ ///
+ public byte PaddingSize;
+
+ ///
+ /// Signature
+ ///
+ public byte[] Signature;
+
+ ///
+ /// Issuer
+ ///
+ public string Issuer;
+
+ ///
+ /// Key Type
+ ///
+ public PublicKeyType KeyType;
+
+ ///
+ /// Name
+ ///
+ public string Name;
+
+ ///
+ /// Expiration time as UNIX Timestamp, used at least for CTCert
+ ///
+ public uint ExpirationTime;
+
+ // This contains the Public Key(i.e. Modulus & Public Exponent)
+ #region RSA
+
+ ///
+ /// Modulus
+ ///
+ public byte[] Modulus;
+
+ ///
+ /// Public Exponent
+ ///
+ public uint PublicExponent;
+
+ #endregion
+
+ // This contains the ECC public key, and is as follows:
+ #region ECC
+
+ ///
+ /// Public Key
+ ///
+ public byte[] PublicKey;
+
+ #endregion
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/CodeSetInfo.cs b/BurnOutSharp.Models/N3DS/CodeSetInfo.cs
new file mode 100644
index 00000000..a76db265
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/CodeSetInfo.cs
@@ -0,0 +1,21 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class CodeSetInfo
+ {
+ ///
+ /// Address
+ ///
+ public byte[] Address;
+
+ ///
+ /// Physical region size (in page-multiples)
+ ///
+ public uint PhysicalRegionSizeInPages;
+
+ ///
+ /// Size (in bytes)
+ ///
+ public uint SizeInBytes;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/Constants.cs b/BurnOutSharp.Models/N3DS/Constants.cs
new file mode 100644
index 00000000..d85148ff
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/Constants.cs
@@ -0,0 +1,25 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ public static class Constants
+ {
+ // ExeFS
+ public static readonly byte[] CodeSegmentName = new byte[] { 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x00, 0x00, 0x00 }; // .code\0\0\0
+
+ // NCCH
+ public const string NCCHMagicNumber = "NCCH";
+
+ // NCSD
+ public const string NCSDMagicNumber = "NCSD";
+
+ // RomFS
+ public const string RomFSMagicNumber = "IVFC";
+ public const uint RomFSSecondMagicNumber = 0x10000;
+
+ // Setup Keys and IVs
+ public static byte[] PlainCounter = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ public static byte[] ExefsCounter = new byte[] { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ public static byte[] RomfsCounter = new byte[] { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ public const int CXTExtendedDataHeaderLength = 0x800;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/ContentChunkRecord.cs b/BurnOutSharp.Models/N3DS/ContentChunkRecord.cs
new file mode 100644
index 00000000..66f7b1a7
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ContentChunkRecord.cs
@@ -0,0 +1,38 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// There is one of these for each content contained in this title.
+ /// (Determined by "Content Count" in the TMD Header).
+ ///
+ ///
+ public sealed class ContentChunkRecord
+ {
+ ///
+ /// Content id
+ ///
+ public uint ContentId;
+
+ ///
+ /// Content index
+ ///
+ ///
+ /// This does not apply to DLC.
+ ///
+ public ContentIndex ContentIndex;
+
+ ///
+ /// Content type
+ ///
+ public TMDContentType ContentType;
+
+ ///
+ /// Content size
+ ///
+ public ulong ContentSize;
+
+ ///
+ /// SHA-256 hash
+ ///
+ public byte[] SHA256Hash;
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp.Models/N3DS/ContentInfoRecord.cs b/BurnOutSharp.Models/N3DS/ContentInfoRecord.cs
new file mode 100644
index 00000000..1a6ef1ab
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ContentInfoRecord.cs
@@ -0,0 +1,24 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// There are 64 of these records, usually only the first is used.
+ ///
+ ///
+ public sealed class ContentInfoRecord
+ {
+ ///
+ /// Content index offset
+ ///
+ public ushort ContentIndexOffset;
+
+ ///
+ /// Content command count [k]
+ ///
+ public ushort ContentCommandCount;
+
+ ///
+ /// SHA-256 hash of the next k content records that have not been hashed yet
+ ///
+ public byte[] UnhashedContentRecordsSHA256Hash;
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp.Models/N3DS/Enums.cs b/BurnOutSharp.Models/N3DS/Enums.cs
new file mode 100644
index 00000000..94ddb9f4
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/Enums.cs
@@ -0,0 +1,229 @@
+using System;
+
+namespace BurnOutSharp.Models.N3DS
+{
+ [Flags]
+ public enum ARM9AccessControlDescriptors : byte
+ {
+ MountNandRoot = 0x01,
+ MountNandroWriteAccess = 0x02,
+ MountTwlnRoot = 0x04,
+ MountWnandRoot = 0x08,
+ MountCardSPI = 0x0F,
+ UseSDIF3 = 0x10,
+ CreateSeed = 0x20,
+ UseCardSPI = 0x40,
+ SDApplication = 0x80,
+ MoundSdmcWriteAccess = 0xF0,
+ }
+
+ [Flags]
+ public enum ARM11LSCFlag0 : byte
+ {
+ IdealProcessor = 0x01 | 0x02,
+
+ AffinityMask = 0x04 | 0x08,
+
+ ///
+ /// Value Description
+ /// 0 Prod (64MB of usable application memory)
+ /// 1 Undefined (unusable)
+ /// 2 Dev1 (96MB of usable application memory)
+ /// 3 Dev2 (80MB of usable application memory)
+ /// 4 Dev3 (72MB of usable application memory)
+ /// 5 Dev4 (32MB of usable application memory)
+ /// 6-7 Undefined Same as Prod?
+ ///
+ Old3DSSystemMode = 0x0F | 0x10 | 0x20 | 0x40,
+ }
+
+ [Flags]
+ public enum ARM11LSCFlag1 : byte
+ {
+ EnableL2Cache = 0x01,
+ Cpuspeed_804MHz = 0x02,
+ }
+
+ [Flags]
+ public enum ARM11LSCFlag2 : byte
+ {
+ ///
+ /// Value Description
+ /// 0 Legacy (use Old3DS system mode)
+ /// 1 Prod (124MB of usable application memory)
+ /// 2 Dev1 (178MB of usable application memory)
+ /// 3 Dev2 (124MB of usable application memory)
+ /// 4-7 Undefined Same as Prod?
+ ///
+ New3DSSystemMode = 0x01 | 0x02 | 0x04 | 0x08,
+ }
+
+ [Flags]
+ public enum BitMasks : byte
+ {
+ FixedCryptoKey = 0x01,
+ NoMountRomFs = 0x02,
+ NoCrypto = 0x04,
+ NewKeyYGenerator = 0x20,
+ }
+
+ public enum ContentIndex : ushort
+ {
+ ///
+ /// Main Content (.CXI for 3DS executable content/.CFA for 3DS Data Archives/.SRL for TWL content)
+ ///
+ MainContent = 0x0000,
+
+ ///
+ /// Home Menu Manual (.CFA)
+ ///
+ HomeMenuManual = 0x0001,
+
+ ///
+ /// DLP Child Container (.CFA)
+ ///
+ DLPChildContainer = 0x0002,
+ }
+
+ public enum ContentPlatform : byte
+ {
+ CTR = 0x01,
+ Snake = 0x02, // New3DS
+ }
+
+ [Flags]
+ public enum ContentType : byte
+ {
+ Data = 0x01,
+ Executable = 0x02,
+ SystemUpdate = 0x04,
+ Manual = 0x08,
+ Child = 0x04 | 0x08,
+ Trial = 0x10,
+ }
+
+ public enum CryptoMethod : byte
+ {
+ Original = 0x00,
+ Seven = 0x01,
+ NineThree = 0x0A,
+ NineSix = 0x0B,
+ }
+
+ [Flags]
+ public enum FilesystemAccessInfo : ulong
+ {
+ CategorySystemApplication = 0x1,
+ CategoryHardwareCheck = 0x2,
+ CategoryFilesystemTool = 0x4,
+ Debug = 0x8,
+ TWLCardBackup = 0x10,
+ TWLNANDData = 0x20,
+ BOSS = 0x40,
+ sdmcRoot = 0x80,
+ Core = 0x100,
+ nandRootroReadOnly = 0x200,
+ nandRootrw = 0x400,
+ nandrootroWriteAccess = 0x800,
+ CategorySystemSettings = 0x1000,
+ Cardboard = 0x2000,
+ ExportImportIVS = 0x4000,
+ sdmcRootWriteOnly = 0x8000,
+ SwitchCleanup = 0x10000, // Introduced in 3.0.0?
+ SavedataMove = 0x20000, // Introduced in 5.0.0
+ Shop = 0x40000, // Introduced in 5.0.0
+ Shell = 0x80000, // Introduced in 5.0.0
+ CategoryHomeMenu = 0x100000, // Introduced in 6.0.0
+ SeedDB = 0x200000, // Introduced in 9.6.0-X FIRM. Home Menu has this bit set starting with 9.6.0-X.
+ }
+
+ public enum FilesystemType : ulong
+ {
+ None = 0,
+ Normal = 1,
+ FIRM = 3,
+ AGB_FIRMSave = 4,
+ }
+
+ public enum MediaCardDeviceType : byte
+ {
+ NORFlash = 0x01,
+ None = 0x02,
+ BT = 0x03,
+ }
+
+ public enum MediaPlatformIndex : byte
+ {
+ CTR = 0x01,
+ }
+
+ public enum MediaTypeIndex : byte
+ {
+ InnerDevice = 0x00,
+ Card1 = 0x01,
+ Card2 = 0x02,
+ ExtendedDevice = 0x03,
+ }
+
+ public enum NCCHFlags
+ {
+ CryptoMethod = 0x03,
+ ContentPlatform = 0x04,
+ ContentTypeBitMask = 0x05,
+ ContentUnitSize = 0x06,
+ BitMasks = 0x07,
+ }
+
+ public enum NCSDFlags
+ {
+ BackupWriteWaitTime = 0x00,
+ MediaCardDevice3X = 0x03,
+ MediaPlatformIndex = 0x04,
+ MediaTypeIndex = 0x05,
+ MediaUnitSize = 0x06,
+ MediaCardDevice2X = 0x07,
+ }
+
+ public enum PublicKeyType : uint
+ {
+ RSA_4096 = 0x00000000,
+ RSA_2048 = 0x01000000,
+ ECDSA = 0x02000000,
+ }
+
+ public enum ResourceLimitCategory
+ {
+ APPLICATION = 0,
+ SYS_APPLET = 1,
+ LIB_APPLET = 2,
+ OTHER = 3,
+ }
+
+ // Note: These are reversed because of how C# reads values
+ public enum SignatureType : uint
+ {
+ RSA_4096_SHA1 = 0x00000100,
+ RSA_2048_SHA1 = 0x01000100,
+ ECDSA_SHA1 = 0x02000100,
+ RSA_4096_SHA256 = 0x03000100,
+ RSA_2048_SHA256 = 0x04000100,
+ ECDSA_SHA256 = 0x05000100,
+ }
+
+ [Flags]
+ public enum StorageInfoOtherAttributes : byte
+ {
+ NotUseROMFS = 0x01,
+ UseExtendedSavedataAccess = 0x02,
+ }
+
+ [Flags]
+ public enum TMDContentType : ushort
+ {
+ Encrypted = 0x0001,
+ Disc = 0x0002,
+ CFM = 0x0004,
+ Optional = 0x4000,
+ Shared = 0x8000,
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/ExeFSFileHeader.cs b/BurnOutSharp.Models/N3DS/ExeFSFileHeader.cs
new file mode 100644
index 00000000..7109f553
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ExeFSFileHeader.cs
@@ -0,0 +1,33 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// There are a maximum of 10 file headers in the ExeFS format. (This maximum
+ /// number of file headers is disputable, with makerom indicating a maximum of
+ /// 8 sections and makecia indicating a maximum of 10. From a non-SDK point of
+ /// view, the ExeFS header format can hold no more than 10 file headers within
+ /// the currently define size of 0x200 bytes.)
+ ///
+ ///
+ public sealed class ExeFSFileHeader
+ {
+ ///
+ /// File name
+ ///
+ public string FileName;
+
+ ///
+ /// File offset
+ ///
+ public uint FileOffset;
+
+ ///
+ /// File size
+ ///
+ public uint FileSize;
+
+ ///
+ /// SHA256 hash calculated over the entire file contents
+ ///
+ public byte[] FileHash;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/ExeFSHeader.cs b/BurnOutSharp.Models/N3DS/ExeFSHeader.cs
new file mode 100644
index 00000000..9c6dda89
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/ExeFSHeader.cs
@@ -0,0 +1,26 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// ExeFS or Executable Filesystem contains information related to the
+ /// executable program, and is the part of the CXI format.
+ ///
+ /// The ExeFS usually contains one or more of the following files:
+ /// - .code Contains the code binary, which can be optionally reverse-LZSS compressed via an exheader flag.
+ /// - logo Contains distribution licensing Binary data.
+ /// - banner Contains the banner which homemenu uses for this CXI.
+ /// - icon Contains the icon which homemenu displays for this CXI.
+ ///
+ ///
+ public sealed class ExeFSHeader
+ {
+ ///
+ /// File headers (10 headers maximum, 16 bytes each)
+ ///
+ public ExeFSFileHeader[] FileHeaders;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/MetaFile.cs b/BurnOutSharp.Models/N3DS/MetaFile.cs
new file mode 100644
index 00000000..6962899a
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/MetaFile.cs
@@ -0,0 +1,31 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class MetaFile
+ {
+ ///
+ /// Title ID dependency list - Taken from the application's ExHeader
+ ///
+ public byte[] TitleIDDependencyList;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved1;
+
+ ///
+ /// Core Version
+ ///
+ public uint CoreVersion;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved2;
+
+ ///
+ /// Icon Data(.ICN) - Taken from the application's ExeFS
+ ///
+ public byte[] IconData;
+ }
+}
\ No newline at end of file
diff --git a/BurnOutSharp.Models/N3DS/NCCHHeader.cs b/BurnOutSharp.Models/N3DS/NCCHHeader.cs
new file mode 100644
index 00000000..34eaaef9
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/NCCHHeader.cs
@@ -0,0 +1,156 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class NCCHHeader
+ {
+ ///
+ /// RSA-2048 signature of the NCCH header, using SHA-256.
+ ///
+ public byte[] RSA2048Signature;
+
+ ///
+ /// Magic ID, always 'NCCH'
+ ///
+ public string MagicID;
+
+ ///
+ /// Content size, in media units (1 media unit = 0x200 bytes)
+ ///
+ public uint ContentSizeInMediaUnits;
+
+ ///
+ /// Partition ID
+ ///
+ public ulong PartitionId;
+
+ ///
+ /// Maker code
+ ///
+ public ushort MakerCode;
+
+ ///
+ /// Version
+ ///
+ public ushort Version;
+
+ ///
+ /// When ncchflag[7] = 0x20 starting with FIRM 9.6.0-X, this is compared with the first output u32 from a
+ /// SHA256 hash. The data used for that hash is 0x18-bytes: [0x10-long title-unique content lock seed]
+ /// [programID from NCCH + 0x118]. This hash is only used for verification of the content lock seed, and
+ /// is not the actual keyY.
+ ///
+ public uint VerificationHash;
+
+ ///
+ /// Program ID
+ ///
+ public ulong ProgramId;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved1;
+
+ ///
+ /// Logo Region SHA-256 hash. (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
+ ///
+ public byte[] LogoRegionHash;
+
+ ///
+ /// Product code
+ ///
+ public byte[] ProductCode;
+
+ ///
+ /// Extended header SHA-256 hash (SHA256 of 2x Alignment Size, beginning at 0x0 of ExHeader)
+ ///
+ public byte[] ExtendedHeaderHash;
+
+ ///
+ /// Extended header size, in bytes
+ ///
+ public uint ExtendedHeaderSizeInBytes;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved2;
+
+ ///
+ /// Flags
+ ///
+ public NCCHHeaderFlags Flags;
+
+ ///
+ /// Plain region offset, in media units
+ ///
+ public uint PlainRegionOffsetInMediaUnits;
+
+ ///
+ /// Plain region size, in media units
+ ///
+ public uint PlainRegionSizeInMediaUnits;
+
+ ///
+ /// Logo Region offset, in media units (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
+ ///
+ public uint LogoRegionOffsetInMediaUnits;
+
+ ///
+ /// Logo Region size, in media units (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11)
+ ///
+ public uint LogoRegionSizeInMediaUnits;
+
+ ///
+ /// ExeFS offset, in media units
+ ///
+ public uint ExeFSOffsetInMediaUnits;
+
+ ///
+ /// ExeFS size, in media units
+ ///
+ public uint ExeFSSizeInMediaUnits;
+
+ ///
+ /// ExeFS hash region size, in media units
+ ///
+ public uint ExeFSHashRegionSizeInMediaUnits;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved3;
+
+ ///
+ /// RomFS offset, in media units
+ ///
+ public uint RomFSOffsetInMediaUnits;
+
+ ///
+ /// RomFS size, in media units
+ ///
+ public uint RomFSSizeInMediaUnits;
+
+ ///
+ /// RomFS hash region size, in media units
+ ///
+ public uint RomFSHashRegionSizeInMediaUnits;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved4;
+
+ ///
+ /// ExeFS superblock SHA-256 hash - (SHA-256 hash, starting at 0x0 of the ExeFS over the number of
+ /// media units specified in the ExeFS hash region size)
+ ///
+ public byte[] ExeFSSuperblockHash;
+
+ ///
+ /// RomFS superblock SHA-256 hash - (SHA-256 hash, starting at 0x0 of the RomFS over the number
+ /// of media units specified in the RomFS hash region size)
+ ///
+ public byte[] RomFSSuperblockHash;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/NCCHHeaderFlags.cs b/BurnOutSharp.Models/N3DS/NCCHHeaderFlags.cs
new file mode 100644
index 00000000..e850b088
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/NCCHHeaderFlags.cs
@@ -0,0 +1,49 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class NCCHHeaderFlags
+ {
+ ///
+ /// Reserved
+ ///
+ public byte Reserved0;
+
+ ///
+ /// Reserved
+ ///
+ public byte Reserved1;
+
+ ///
+ /// Reserved
+ ///
+ public byte Reserved2;
+
+ ///
+ /// Crypto Method: When this is non-zero, a NCCH crypto method using two keyslots is used.
+ ///
+ public CryptoMethod CryptoMethod;
+
+ ///
+ /// Content Platform: 1 = CTR, 2 = snake (New 3DS).
+ ///
+ public ContentPlatform ContentPlatform;
+
+ ///
+ /// Content Type Bit-masks: Data = 0x1, Executable = 0x2, SystemUpdate = 0x4, Manual = 0x8,
+ /// Child = (0x4|0x8), Trial = 0x10. When 'Data' is set, but not 'Executable', NCCH is a CFA.
+ /// Otherwise when 'Executable' is set, NCCH is a CXI.
+ ///
+ public ContentType MediaPlatformIndex;
+
+ ///
+ /// Content Unit Size i.e. u32 ContentUnitSize = 0x200*2^flags[6];
+ ///
+ public byte ContentUnitSize;
+
+ ///
+ /// Bit-masks: FixedCryptoKey = 0x1, NoMountRomFs = 0x2, NoCrypto = 0x4, using a new keyY
+ /// generator = 0x20(starting with FIRM 9.6.0-X).
+ ///
+ public BitMasks BitMasks;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/NCSDHeader.cs b/BurnOutSharp.Models/N3DS/NCSDHeader.cs
new file mode 100644
index 00000000..7b718b7f
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/NCSDHeader.cs
@@ -0,0 +1,196 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// There are two known specialisations of the NCSD container format:
+ /// - The CTR Cart Image (CCI) format, the 3DS' raw NAND format
+ /// - CCI is the format of game ROM images.
+ ///
+ /// CTR System Update (CSU) is a variant of CCI, where the only difference
+ /// is in the file extension.
+ ///
+ ///
+ public sealed class NCSDHeader
+ {
+ #region Common to all NCSD files
+
+ ///
+ /// RSA-2048 SHA-256 signature of the NCSD header
+ ///
+ public byte[] RSA2048Signature;
+
+ ///
+ /// Size of the NCSD image, in media units (1 media unit = 0x200 bytes)
+ ///
+ public uint ImageSizeInMediaUnits;
+
+ ///
+ /// Media ID
+ ///
+ public byte[] MediaId;
+
+ ///
+ /// Partitions FS type (0=None, 1=Normal, 3=FIRM, 4=AGB_FIRM save)
+ ///
+ public FilesystemType PartitionsFSType;
+
+ ///
+ /// Partitions crypt type (each byte corresponds to a partition in the partition table)
+ ///
+ public byte[] PartitionsCryptType;
+
+ ///
+ /// Offset & Length partition table, in media units
+ ///
+ public PartitionTableEntry[] PartitionsTable;
+
+ #endregion
+
+ #region CTR Cart Image (CCI) Specific
+
+ ///
+ /// Exheader SHA-256 hash
+ ///
+ public byte[] ExheaderHash;
+
+ ///
+ /// Additional header size
+ ///
+ public uint AdditionalHeaderSize;
+
+ ///
+ /// Sector zero offset
+ ///
+ public uint SectorZeroOffset;
+
+ ///
+ /// Partition Flags
+ ///
+ public byte[] PartitionFlags;
+
+ ///
+ /// Partition ID table
+ ///
+ public byte[][] PartitionIdTable;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved1;
+
+ ///
+ /// Reserved?
+ ///
+ public byte[] Reserved2;
+
+ ///
+ /// Support for this was implemented with 9.6.0-X FIRM. Bit0=1 enables using bits 1-2, it's unknown
+ /// what these two bits are actually used for(the value of these two bits get compared with some other
+ /// value during NCSD verification/loading). This appears to enable a new, likely hardware-based,
+ /// antipiracy check on cartridges.
+ ///
+ public byte FirmUpdateByte1;
+
+ ///
+ /// Support for this was implemented with 9.6.0-X FIRM, see below regarding save crypto.
+ ///
+ public byte FirmUpdateByte2;
+
+ #endregion
+
+ #region Raw NAND Format Specific
+
+ ///
+ /// Unknown
+ ///
+ public byte[] Unknown;
+
+ ///
+ /// Encrypted MBR partition-table, for the TWL partitions(key-data used for this keyslot is console-unique).
+ ///
+ public byte[] EncryptedMBR;
+
+ #endregion
+
+ #region Card Info Header
+
+ ///
+ /// CARD2: Writable Address In Media Units (For 'On-Chip' Savedata). CARD1: Always 0xFFFFFFFF.
+ ///
+ public byte[] CARD2WritableAddressMediaUnits;
+
+ ///
+ /// Card Info Bitmask
+ ///
+ public byte[] CardInfoBytemask;
+
+ ///
+ /// Reserved1
+ ///
+ public byte[] Reserved3;
+
+ ///
+ /// Title version
+ ///
+ public ushort TitleVersion;
+
+ ///
+ /// Card revision
+ ///
+ public ushort CardRevision;
+
+ ///
+ /// Reserved2
+ ///
+ public byte[] Reserved4;
+
+ ///
+ /// Card seed keyY (first u64 is Media ID (same as first NCCH partitionId))
+ ///
+ public byte[] CardSeedKeyY;
+
+ ///
+ /// Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see CTRCARD_SECSEED) ///
+ public byte[] EncryptedCardSeed;
+
+ ///
+ /// Card seed AES-MAC
+ ///
+ public byte[] CardSeedAESMAC;
+
+ ///
+ /// Card seed nonce
+ ///
+ public byte[] CardSeedNonce;
+
+ ///
+ /// Reserved3
+ ///
+ public byte[] Reserved5;
+
+ ///
+ /// Copy of first NCCH header (excluding RSA signature)
+ ///
+ public NCCHHeader BackupHeader;
+
+ #endregion
+
+ #region Development Card Info Header Extension
+
+ ///
+ /// CardDeviceReserved1
+ ///
+ public byte[] CardDeviceReserved1;
+
+ ///
+ /// TitleKey
+ ///
+ public byte[] TitleKey;
+
+ ///
+ /// CardDeviceReserved2
+ ///
+ public byte[] CardDeviceReserved2;
+
+ #endregion
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/PartitionTableEntry.cs b/BurnOutSharp.Models/N3DS/PartitionTableEntry.cs
new file mode 100644
index 00000000..9817f4ad
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/PartitionTableEntry.cs
@@ -0,0 +1,19 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// Offset and Length partition table, in media units
+ ///
+ ///
+ public sealed class PartitionTableEntry
+ {
+ ///
+ /// Offset
+ ///
+ public uint Offset;
+
+ ///
+ /// Length
+ ///
+ public uint Length;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/RomFSHeader.cs b/BurnOutSharp.Models/N3DS/RomFSHeader.cs
new file mode 100644
index 00000000..a951cd23
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/RomFSHeader.cs
@@ -0,0 +1,85 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// RomFS (or Read-Only Filesystem) is part of the NCCH format, and is
+ /// used as external file storage.
+ ///
+ ///
+ public sealed class RomFSHeader
+ {
+ ///
+ /// Master hash size
+ ///
+ public uint MasterHashSize;
+
+ ///
+ /// Level 1 logical offset
+ ///
+ public ulong Level1LogicalOffset;
+
+ ///
+ /// Level 1 hashdata size
+ ///
+ public ulong Level1HashdataSize;
+
+ ///
+ /// Level 1 block size, in log2
+ ///
+ public uint Level1BlockSizeLog2;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved1;
+
+ ///
+ /// Level 2 logical offset
+ ///
+ public ulong Level2LogicalOffset;
+
+ ///
+ /// Level 2 hashdata size
+ ///
+ public ulong Level2HashdataSize;
+
+ ///
+ /// Level 2 block size, in log2
+ ///
+ public uint Level2BlockSizeLog2;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved2;
+
+ ///
+ /// Level 3 logical offset
+ ///
+ public ulong Level3LogicalOffset;
+
+ ///
+ /// Level 3 hashdata size
+ ///
+ public ulong Level3HashdataSize;
+
+ ///
+ /// Level 3 block size, in log2
+ ///
+ public uint Level3BlockSizeLog2;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved3;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved4;
+
+ ///
+ /// Optional info size.
+ ///
+ public uint OptionalInfoSize;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/StorageInfo.cs b/BurnOutSharp.Models/N3DS/StorageInfo.cs
new file mode 100644
index 00000000..d5a1158c
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/StorageInfo.cs
@@ -0,0 +1,34 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// Used in FSReg:Register.
+ ///
+ ///
+ public sealed class StorageInfo
+ {
+ ///
+ /// Extdata ID
+ ///
+ public byte[] ExtdataID;
+
+ ///
+ /// System savedata IDs
+ ///
+ public byte[] SystemSavedataIDs;
+
+ ///
+ /// Storage accessible unique IDs
+ ///
+ public byte[] StorageAccessibleUniqueIDs;
+
+ ///
+ /// Filesystem access info
+ ///
+ public byte[] FilesystemAccessInfo;
+
+ ///
+ /// Other attributes
+ ///
+ public StorageInfoOtherAttributes OtherAttributes;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/SystemControlInfo.cs b/BurnOutSharp.Models/N3DS/SystemControlInfo.cs
new file mode 100644
index 00000000..339960cc
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/SystemControlInfo.cs
@@ -0,0 +1,66 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class SystemControlInfo
+ {
+ ///
+ /// Application title (default is "CtrApp")
+ ///
+ public char[] ApplicationTitle;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved1;
+
+ ///
+ /// Flag (bit 0: CompressExefsCode, bit 1: SDApplication)
+ ///
+ public byte Flag;
+
+ ///
+ /// Remaster version
+ ///
+ public byte[] RemasterVersion;
+
+ ///
+ /// Text code set info
+ ///
+ public CodeSetInfo TextCodesetInfo;
+
+ ///
+ /// Stack size
+ ///
+ public uint StackSize;
+
+ ///
+ /// Read-only code set info
+ ///
+ public CodeSetInfo ReadOnlyCodeSetInfo;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved2;
+
+ ///
+ /// Data code set info
+ ///
+ public CodeSetInfo DataCodeSetInfo;
+
+ ///
+ /// BSS size
+ ///
+ public uint BSSSize;
+
+ ///
+ /// Dependency module (program ID) list
+ ///
+ public byte[][] DependencyModuleList;
+
+ ///
+ /// SystemInfo
+ ///
+ public SystemInfo SystemInfo;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/SystemInfo.cs b/BurnOutSharp.Models/N3DS/SystemInfo.cs
new file mode 100644
index 00000000..8a7abae9
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/SystemInfo.cs
@@ -0,0 +1,21 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ public sealed class SystemInfo
+ {
+ ///
+ /// SaveData Size
+ ///
+ public ulong SaveDataSize;
+
+ ///
+ /// Jump ID
+ ///
+ public byte[] JumpID;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/Ticket.cs b/BurnOutSharp.Models/N3DS/Ticket.cs
new file mode 100644
index 00000000..048990f6
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/Ticket.cs
@@ -0,0 +1,174 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// A format used to store an encrypted titlekey (using 128-Bit AES-CBC).
+ /// With 3DS, the Ticket format was updated (now v1) from Wii/DSi format (v0).
+ ///
+ ///
+ public sealed class Ticket
+ {
+ ///
+ /// Signature Type
+ ///
+ public SignatureType SignatureType;
+
+ ///
+ /// Signature size
+ ///
+ public ushort SignatureSize;
+
+ ///
+ /// Padding size
+ ///
+ public byte PaddingSize;
+
+ ///
+ /// Signature
+ ///
+ public byte[] Signature;
+
+ ///
+ /// Issuer
+ ///
+ public string Issuer;
+
+ ///
+ /// ECC PublicKey
+ ///
+ public byte[] ECCPublicKey;
+
+ ///
+ /// Version (For 3DS this is always 1)
+ ///
+ public byte Version;
+
+ ///
+ /// CaCrlVersion
+ ///
+ public byte CaCrlVersion;
+
+ ///
+ /// SignerCrlVersion
+ ///
+ public byte SignerCrlVersion;
+
+ ///
+ /// TitleKey (normal-key encrypted using one of the common keyYs; see below)
+ ///
+ ///
+ /// The titlekey is decrypted by using the AES engine with the ticket common-key keyslot.
+ /// The keyY is selected through an index (ticket offset 0xB1) into a plaintext array
+ /// of 6 keys ("common keyYs") stored in the data section of Process9. AES-CBC mode is used
+ /// where the IV is the big-endian titleID. Note that on a retail unit index0 is a retail keyY,
+ /// while on a dev-unit index0 is the dev common-key which is a normal-key.
+ /// (On retail for these keyYs, the hardware key-scrambler is used)
+ ///
+ /// The titlekey is used to decrypt content downloaded from the CDN using 128-bit AES-CBC with
+ /// the content index (as big endian u16, padded with trailing zeroes) as the IV.
+ ///
+ public byte[] TitleKey;
+
+ ///
+ /// Reserved
+ ///
+ public byte Reserved1;
+
+ ///
+ /// TicketID
+ ///
+ public ulong TicketID;
+
+ ///
+ /// ConsoleID
+ ///
+ public uint ConsoleID;
+
+ ///
+ /// TitleID
+ ///
+ public ulong TitleID;
+
+ ///
+ /// Reserved
+ ///
+ public ushort Reserved2;
+
+ ///
+ /// Ticket title version
+ ///
+ ///
+ /// The Ticket Title Version is generally the same as the title version stored in the
+ /// Title Metadata. Although it doesn't have to match the TMD version to be valid.
+ ///
+ public ushort TicketTitleVersion;
+
+ ///
+ /// Reserved
+ ///
+ public ulong Reserved3;
+
+ ///
+ /// License Type
+ ///
+ public byte LicenseType;
+
+ ///
+ /// Index to the common keyY used for this ticket, usually 0x1 for retail system titles;
+ /// see below.
+ ///
+ public byte CommonKeyYIndex;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved4;
+
+ ///
+ /// eShop Account ID?
+ ///
+ public uint eShopAccountID;
+
+ ///
+ /// Reserved
+ ///
+ public byte Reserved5;
+
+ ///
+ /// Audit
+ ///
+ public byte Audit;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved6;
+
+ ///
+ /// Limits
+ ///
+ ///
+ /// In demos, the first u32 in the "Limits" section is 0x4, then the second u32 is the max-playcount.
+ ///
+ public int[] Limits;
+
+ ///
+ /// The Content Index of a ticket has its own size defined within itself,
+ /// with seemingly a minimal of 20 bytes, the second u32 in big endian defines
+ /// the full value of X.
+ ///
+ public int ContentIndexSize;
+
+ ///
+ /// Content Index
+ ///
+ public byte[] ContentIndex;
+
+ ///
+ /// Certificate chain
+ ///
+ ///
+ /// https://www.3dbrew.org/wiki/Ticket#Certificate_Chain
+ ///
+ public Certificate[] CertificateChain;
+ }
+}
diff --git a/BurnOutSharp.Models/N3DS/TitleMetadata.cs b/BurnOutSharp.Models/N3DS/TitleMetadata.cs
new file mode 100644
index 00000000..b99c4ca1
--- /dev/null
+++ b/BurnOutSharp.Models/N3DS/TitleMetadata.cs
@@ -0,0 +1,150 @@
+namespace BurnOutSharp.Models.N3DS
+{
+ ///
+ /// A format used to store information about a title (installed title, DLC, etc.)
+ /// and all its installed contents, including which contents they consist of and
+ /// their SHA256 hashes.
+ ///
+ ///
+ public sealed class TitleMetadata
+ {
+ ///
+ /// Signature Type
+ ///
+ public SignatureType SignatureType;
+
+ ///
+ /// Signature size
+ ///
+ public ushort SignatureSize;
+
+ ///
+ /// Padding size
+ ///
+ public byte PaddingSize;
+
+ ///
+ /// Signature
+ ///
+ public byte[] Signature;
+
+ ///
+ /// Signature Issuer
+ ///
+ public byte[] SignatureIssuer;
+
+ ///
+ /// Version
+ ///
+ public byte Version;
+
+ ///
+ /// CaCrlVersion
+ ///
+ public byte CaCrlVersion;
+
+ ///
+ /// SignerCrlVersion
+ ///
+ public byte SignerCrlVersion;
+
+ ///
+ /// Reserved
+ ///
+ public byte Reserved1;
+
+ ///
+ /// System Version
+ ///
+ public ulong SystemVersion;
+
+ ///
+ /// TitleID
+ ///
+ public ulong TitleID;
+
+ ///
+ /// Title Type
+ ///
+ public uint TitleType;
+
+ ///
+ /// Group ID
+ ///
+ public ushort GroupID;
+
+ ///
+ /// Save Data Size in Little Endian (Bytes) (Also SRL Public Save Data Size)
+ ///
+ public uint SaveDataSize;
+
+ ///
+ /// SRL Private Save Data Size in Little Endian (Bytes)
+ ///
+ public uint SRLPrivateSaveDataSize;
+
+ ///
+ /// Reserved
+ ///
+ public uint Reserved2;
+
+ ///
+ /// SRL Flag
+ ///
+ public byte SRLFlag;
+
+ ///
+ /// Reserved
+ ///
+ public byte[] Reserved3;
+
+ ///
+ /// Access Rights
+ ///
+ public uint AccessRights;
+
+ ///
+ /// Title Version
+ ///
+ public ushort TitleVersion;
+
+ ///
+ /// Content Count
+ ///
+ public ushort ContentCount;
+
+ ///
+ /// Boot Content
+ ///
+ public ushort BootContent;
+
+ ///
+ /// Padding
+ ///
+ public ushort Padding;
+
+ ///
+ /// SHA-256 Hash of the Content Info Records
+ ///
+ public byte[] SHA256HashContentInfoRecords;
+
+ ///
+ /// There are 64 of these records, usually only the first is used.
+ ///
+ public ContentInfoRecord[] ContentInfoRecords;
+
+ ///
+ /// There is one of these for each content contained in this title.
+ /// (Determined by "Content Count" in the TMD Header).
+ ///
+ public ContentChunkRecord[] ContentChunkRecords;
+
+ ///
+ /// Certificate chain
+ ///
+ ///
+ /// https://www.3dbrew.org/wiki/Title_metadata#Certificate_Chain
+ ///
+ public Certificate[] CertificateChain;
+ }
+}
\ No newline at end of file