#pragma once typedef enum { NCCH_MEMERROR = -1, SAVE_DATA_TOO_LARGE = -2, NCCH_SECTION_NOT_EXIST = -3, UNABLE_TO_LOAD_NCCH_KEY = -4, NCCH_EXPORT_BUFFER_TOO_SMALL = -5, NO_ROMFS_IN_CFA = -6, NO_EXHEADER_IN_CXI = -7, NO_EXEFS_IN_CXI = -8, // SigCheck Errors CXI_CORRUPT = -9, ACCESSDESC_SIG_BAD = -10, NCCH_HDR_SIG_BAD = -11, // HashCheck Errors EXHDR_CORRUPT = -12, LOGO_CORRUPT = -13, EXEFS_CORRUPT = -14, ROMFS_CORRUPT = -15, // Others NCCH_BAD_RSF_SET = -16, DATA_POS_DNE = -17, } ncch_errors; typedef enum { ncch_exhdr = 1, ncch_exefs, ncch_romfs, } ncch_section; typedef enum { ncchflag_CONTENT_KEYX = 3, ncchflag_CONTENT_PLATFORM = 4, ncchflag_CONTENT_TYPE = 5, ncchflag_CONTENT_BLOCK_SIZE = 6, ncchflag_OTHER_FLAG = 7 } ncch_flags; typedef enum { otherflag_Clear = 0, otherflag_FixedCryptoKey = (1 << 0), otherflag_NoMountRomFs = (1 << 1), otherflag_NoCrypto = (1 << 2), } ncch_otherflag_bitmask; typedef enum { form_Unassigned, form_SimpleContent, form_ExecutableWithoutRomfs, form_Executable } ncch_form_type; typedef enum { content_Application, content_SystemUpdate, content_Manual, content_Child, content_Trial, content_ExtendedSystemUpdate } ncch_content_bitmask; typedef enum { platform_CTR = 0x1, platform_SNAKE = 0x2 } ncch_platform; typedef enum { keyx_regular = 0x00, keyx_7_0 = 0x01, keyx_9_3 = 0x0A, keyx_9_6 = 0x0B, } ncch_keyx_id; typedef struct { u16 formatVersion; u32 exhdrOffset; u32 exhdrSize; u32 acexOffset; u32 acexSize; u64 logoOffset; u64 logoSize; u64 plainRegionOffset; u64 plainRegionSize; u64 exefsOffset; u64 exefsSize; u64 exefsHashDataSize; u64 romfsOffset; u64 romfsSize; u64 romfsHashDataSize; u64 titleId; u64 programId; } ncch_info; typedef struct { u8 signature[0x100]; u8 magic[4]; u8 ncchSize[4]; u8 titleId[8]; u8 makerCode[2]; u8 formatVersion[2]; u8 padding0[4]; u8 programId[8]; u8 padding1[0x10]; u8 logoHash[0x20]; // SHA-256 over the entire logo region u8 productCode[0x10]; u8 exhdrHash[0x20]; // SHA-256 over exhdrSize of the exhdr region u8 exhdrSize[4]; u8 padding2[4]; u8 flags[8]; u8 plainRegionOffset[4]; u8 plainRegionSize[4]; u8 logoOffset[4]; u8 logoSize[4]; u8 exefsOffset[4]; u8 exefsSize[4]; u8 exefsHashSize[4]; u8 padding4[4]; u8 romfsOffset[4]; u8 romfsSize[4]; u8 romfsHashSize[4]; u8 padding5[4]; u8 exefsHash[0x20]; u8 romfsHash[0x20]; } ncch_hdr; // NCCH Read Functions int VerifyNcch(u8 *ncch, keys_struct *keys, bool checkHash, bool suppressOutput); int ModifyNcchIds(u8 *ncch, u8 *titleId, u8 *programId, keys_struct *keys); void ReadNcchHdr(ncch_hdr *hdr, FILE *fp); u8* GetNcchHdrSig(ncch_hdr *hdr); u8* GetNcchHdrData(ncch_hdr *hdr); u32 GetNcchHdrSigLen(ncch_hdr *hdr); u32 GetNcchHdrDataLen(ncch_hdr *hdr); bool IsNcch(FILE *fp, u8 *buf); bool IsCfa(ncch_hdr* hdr); bool IsUpdateCfa(ncch_hdr* hdr); u32 GetNcchBlockSize(ncch_hdr* hdr); u64 GetNcchSize(ncch_hdr* hdr); bool IsNcchEncrypted(ncch_hdr *hdr); bool SetNcchKeys(keys_struct *keys, ncch_hdr *hdr); int GetNcchInfo(ncch_info *ctx, ncch_hdr *header); void GetNcchAesCounter(u8 ctr[16], u64 titleId, u8 type); void CryptNcchRegion(u8 *buffer, u64 size, u64 src_pos, u64 titleId, u8 key[16], u8 type);