using System.Runtime.InteropServices; namespace SabreTools.Data.Models.N3DS { /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public sealed class NCCHHeader { /// /// RSA-2048 signature of the NCCH header, using SHA-256. /// /// 0x100 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)] public byte[] RSA2048Signature = new byte[0x100]; /// /// Magic ID, always 'NCCH' /// /// 4 bytes [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)] public string MagicID = string.Empty; /// /// 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 /// /// 8 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] ProgramId = new byte[8]; /// /// Reserved /// /// 0x10 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)] public byte[] Reserved1 = new byte[0x10]; /// /// Logo Region SHA-256 hash. (For applications built with SDK 5+) (Supported from firmware: 5.0.0-11) /// /// 0x20 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public byte[] LogoRegionHash = new byte[0x20]; /// /// Product code /// /// 0x10 bytes [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x10)] public string ProductCode = string.Empty; /// /// Extended header SHA-256 hash (SHA256 of 2x Alignment Size, beginning at 0x0 of ExHeader) /// /// 0x20 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public byte[] ExtendedHeaderHash = new byte[0x20]; /// /// Extended header size, in bytes /// public uint ExtendedHeaderSizeInBytes; /// /// Reserved /// public uint Reserved2; /// /// Flags /// public NCCHHeaderFlags Flags = new(); /// /// 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 uint 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 uint 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) /// /// 0x20 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public byte[] ExeFSSuperblockHash = new byte[0x20]; /// /// 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) /// /// 0x20 bytes [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public byte[] RomFSSuperblockHash = new byte[0x20]; } }