namespace SabreTools.Data.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 /// /// 0x100 bytes public byte[] RSA2048Signature { get; set; } = new byte[0x100]; /// /// Magic Number 'NCSD' /// public string MagicNumber { get; set; } = string.Empty; /// /// Size of the NCSD image, in media units (1 media unit = 0x200 bytes) /// public uint ImageSizeInMediaUnits { get; set; } /// /// Media ID /// /// 8 bytes public byte[] MediaId { get; set; } = new byte[8]; /// /// Partitions FS type (0=None, 1=Normal, 3=FIRM, 4=AGB_FIRM save) /// public FilesystemType PartitionsFSType { get; set; } /// /// Partitions crypt type (each byte corresponds to a partition in the partition table) /// /// 8 bytes public byte[] PartitionsCryptType { get; set; } = new byte[8]; /// /// Offset & Length partition table, in media units /// public PartitionTableEntry[] PartitionsTable { get; set; } = []; #endregion #region CTR Cart Image (CCI) Specific /// /// Exheader SHA-256 hash /// /// 0x20 bytes public byte[] ExheaderHash { get; set; } = new byte[0x200]; /// /// Additional header size /// public uint AdditionalHeaderSize { get; set; } /// /// Sector zero offset /// public uint SectorZeroOffset { get; set; } /// /// Partition Flags /// public byte[] PartitionFlags { get; set; } = []; /// /// Partition ID table /// public ulong[]? PartitionIdTable { get; set; } /// /// Reserved /// /// 0x20 bytes public byte[] Reserved1 { get; set; } = new byte[0x20]; /// /// Reserved? /// /// 0x0E bytes public byte[] Reserved2 { get; set; } = new byte[0x0E]; /// /// 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 { get; set; } /// /// Support for this was implemented with 9.6.0-X FIRM, see below regarding save crypto. /// public byte FirmUpdateByte2 { get; set; } #endregion #region Raw NAND Format Specific /// /// Unknown /// /// 0x5E bytes public byte[] Unknown { get; set; } = new byte[0x5E]; /// /// Encrypted MBR partition-table, for the TWL partitions(key-data used for this keyslot is console-unique). /// /// 0x42 bytes public byte[] EncryptedMBR { get; set; } = new byte[0x42]; #endregion } }