2016-11-28 01:19:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "common.h"
|
2016-12-06 00:28:29 +01:00
|
|
|
#include "exefs.h"
|
2020-10-26 23:10:36 +01:00
|
|
|
#include "seedsave.h"
|
2016-11-28 01:19:12 +01:00
|
|
|
|
|
|
|
#define NCCH_MEDIA_UNIT 0x200
|
|
|
|
|
|
|
|
#define NCCH_EXTHDR_SIZE 0x800 // NCCH header says 0x400, which is not the full thing
|
|
|
|
#define NCCH_EXTHDR_OFFSET 0x200
|
|
|
|
|
2016-12-13 00:20:00 +01:00
|
|
|
#define NCCH_ENCRYPTED(ncch) (!((ncch)->flags[7] & 0x04))
|
2017-01-28 13:47:37 +01:00
|
|
|
#define NCCH_IS_CXI(ncch) ((ncch)->flags[5] & 0x02)
|
2017-11-03 16:11:29 +01:00
|
|
|
#define NCCH_IS_FIRM(ncch) (((ncch)->programId >> 32) == 0x00040138)
|
2017-10-16 02:02:24 +02:00
|
|
|
#define NCCH_IS_GBAVC(exhdr) (getle32((exhdr)->aci_data + 8) == 0x00000202)
|
2017-01-28 13:47:37 +01:00
|
|
|
|
2017-01-31 16:16:26 +01:00
|
|
|
#define NCCH_NOCRYPTO 0x0004
|
|
|
|
#define NCCH_STDCRYPTO 0x0000
|
2017-01-30 22:06:26 +01:00
|
|
|
#define NCCH_GET_CRYPTO(ncch) (!NCCH_ENCRYPTED(ncch) ? NCCH_NOCRYPTO : (((ncch)->flags[3] << 8) | ((ncch)->flags[7]&(0x01|0x20))))
|
2017-01-28 13:47:37 +01:00
|
|
|
|
|
|
|
// wrapper defines
|
|
|
|
#define DecryptNcch(data, offset, size, ncch, exefs) CryptNcch(data, offset, size, ncch, exefs, NCCH_NOCRYPTO)
|
|
|
|
#define EncryptNcch(data, offset, size, ncch, exefs, crypto) CryptNcch(data, offset, size, ncch, exefs, crypto)
|
|
|
|
#define DecryptNcchSequential(data, offset, size) CryptNcchSequential(data, offset, size, NCCH_NOCRYPTO)
|
|
|
|
#define EncryptNcchSequential(data, offset, size, crypto) CryptNcchSequential(data, offset, size, crypto)
|
2016-11-28 23:38:54 +01:00
|
|
|
|
2016-11-28 01:19:12 +01:00
|
|
|
// see: https://www.3dbrew.org/wiki/NCCH/Extended_Header
|
|
|
|
// very limited, contains only required stuff
|
|
|
|
typedef struct {
|
2018-03-27 00:28:24 +02:00
|
|
|
// SCI (system control info)
|
2016-11-28 01:19:12 +01:00
|
|
|
char name[8];
|
2018-03-27 00:28:24 +02:00
|
|
|
u8 reserved0[0x5];
|
2017-09-08 03:12:04 +02:00
|
|
|
u8 flag; // bit 1 for SD, bit 0 for compressed .code
|
2016-12-19 01:33:30 +01:00
|
|
|
u16 remaster_version;
|
|
|
|
u8 sci_data[0x30];
|
|
|
|
u8 dependencies[0x180];
|
2018-03-27 00:28:24 +02:00
|
|
|
u64 savedata_size;
|
|
|
|
u64 jump_id;
|
|
|
|
u8 reserved1[0x30];
|
|
|
|
// ACI (access control info)
|
|
|
|
u64 aci_title_id;
|
|
|
|
u32 aci_core_version;
|
|
|
|
u8 aci_data[0x200 - 0xC];
|
|
|
|
// signature and key
|
2016-12-19 01:33:30 +01:00
|
|
|
u8 signature[0x100];
|
|
|
|
u8 public_key[0x100];
|
2018-03-27 00:28:24 +02:00
|
|
|
// limitACI (access control info)
|
|
|
|
u64 aci_limit_title_id;
|
|
|
|
u32 aci_limit_core_version;
|
|
|
|
u8 aci_limit_data[0x200 - 0xC];
|
2019-05-08 00:18:34 +02:00
|
|
|
} __attribute__((packed, aligned(16))) NcchExtHeader;
|
2016-11-28 01:19:12 +01:00
|
|
|
|
|
|
|
// see: https://www.3dbrew.org/wiki/NCCH#NCCH_Header
|
|
|
|
typedef struct {
|
|
|
|
u8 signature[0x100];
|
|
|
|
u8 magic[0x4];
|
|
|
|
u32 size;
|
|
|
|
u64 partitionId;
|
|
|
|
u16 makercode;
|
|
|
|
u16 version;
|
2016-12-06 00:28:29 +01:00
|
|
|
u32 hash_seed;
|
2016-11-28 01:19:12 +01:00
|
|
|
u64 programId;
|
|
|
|
u8 reserved0[0x10];
|
|
|
|
u8 hash_logo[0x20];
|
|
|
|
char productcode[0x10];
|
|
|
|
u8 hash_exthdr[0x20];
|
|
|
|
u32 size_exthdr;
|
|
|
|
u8 reserved1[0x4];
|
|
|
|
u8 flags[0x8];
|
|
|
|
u32 offset_plain;
|
|
|
|
u32 size_plain;
|
|
|
|
u32 offset_logo;
|
|
|
|
u32 size_logo;
|
|
|
|
u32 offset_exefs;
|
|
|
|
u32 size_exefs;
|
|
|
|
u32 size_exefs_hash;
|
|
|
|
u8 reserved2[0x4];
|
|
|
|
u32 offset_romfs;
|
|
|
|
u32 size_romfs;
|
|
|
|
u32 size_romfs_hash;
|
|
|
|
u8 reserved3[0x4];
|
|
|
|
u8 hash_exefs[0x20];
|
|
|
|
u8 hash_romfs[0x20];
|
2016-12-08 22:08:19 +01:00
|
|
|
} __attribute__((packed, aligned(16))) NcchHeader;
|
2016-11-28 01:19:12 +01:00
|
|
|
|
|
|
|
u32 ValidateNcchHeader(NcchHeader* header);
|
2017-01-30 22:06:26 +01:00
|
|
|
u32 SetNcchKey(NcchHeader* ncch, u16 crypto, u32 keyid);
|
|
|
|
u32 SetupNcchCrypto(NcchHeader* ncch, u16 crypt_to);
|
2017-06-01 15:11:41 +02:00
|
|
|
u32 CryptNcch(void* data, u32 offset, u32 size, NcchHeader* ncch, ExeFsHeader* exefs, u16 crypto);
|
|
|
|
u32 CryptNcchSequential(void* data, u32 offset, u32 size, u16 crypto);
|
|
|
|
u32 SetNcchSdFlag(void* data);
|
2020-10-26 23:10:36 +01:00
|
|
|
u32 SetupSystemForNcch(NcchHeader* ncch, bool to_emunand);
|