mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-12-27 19:06:01 +00:00
Match changes to the XCI page in Switchbrew.
This commit is contained in:
parent
86dbe3ffd8
commit
460bee888b
2 changed files with 30 additions and 30 deletions
|
@ -31,14 +31,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GAMECARD_HEAD_MAGIC 0x48454144 /* "HEAD". */
|
||||
#define GAMECARD_HEAD_MAGIC 0x48454144 /* "HEAD". */
|
||||
|
||||
#define GAMECARD_MEDIA_UNIT_SIZE 0x200
|
||||
#define GAMECARD_MEDIA_UNIT_OFFSET(x) ((u64)(x) * GAMECARD_MEDIA_UNIT_SIZE)
|
||||
#define GAMECARD_PAGE_SIZE 0x200
|
||||
#define GAMECARD_PAGE_OFFSET(x) ((u64)(x) * GAMECARD_PAGE_SIZE)
|
||||
|
||||
#define GAMECARD_UPDATE_TID SYSTEM_UPDATE_TID
|
||||
#define GAMECARD_UPDATE_TID SYSTEM_UPDATE_TID
|
||||
|
||||
#define GAMECARD_CERTIFICATE_OFFSET 0x7000
|
||||
#define GAMECARD_CERTIFICATE_OFFSET 0x7000
|
||||
|
||||
/// Encrypted using AES-128-ECB with the common titlekek generator key (stored in the .rodata segment from the Lotus firmware).
|
||||
typedef struct {
|
||||
|
@ -123,8 +123,8 @@ typedef enum {
|
|||
typedef enum {
|
||||
GameCardFwVersion_ForDev = 0,
|
||||
GameCardFwVersion_ForProd = BIT(0),
|
||||
GameCardFwVersion_ForProdSince400NUP = BIT(1), ///< cup_version >= 268435456 (4.0.0-0.0) in GameCardHeaderEncryptedArea.
|
||||
GameCardFwVersion_ForProdSince1100NUP = BIT(2) ///< cup_version >= 738197504 (11.0.0-0.0) in GameCardHeaderEncryptedArea.
|
||||
GameCardFwVersion_ForProdSince400NUP = BIT(1), ///< upp_version >= 268435456 (4.0.0-0.0) in GameCardInfo.
|
||||
GameCardFwVersion_ForProdSince1100NUP = BIT(2) ///< upp_version >= 738197504 (11.0.0-0.0) in GameCardInfo.
|
||||
} GameCardFwVersion;
|
||||
|
||||
typedef enum {
|
||||
|
@ -148,40 +148,40 @@ typedef struct {
|
|||
u32 wait_2_time_read; ///< Always 0.
|
||||
u32 wait_1_time_write; ///< Always 0.
|
||||
u32 wait_2_time_write; ///< Always 0.
|
||||
VersionType2 fw_mode;
|
||||
VersionType1 cup_version;
|
||||
VersionType2 fw_mode; ///< Current SdkAddonVersion.
|
||||
VersionType1 upp_version; ///< Bundled system update version.
|
||||
u8 compatibility_type; ///< GameCardCompatibilityType.
|
||||
u8 reserved_1[0x3];
|
||||
u64 cup_hash;
|
||||
u64 cup_id; ///< Must match GAMECARD_UPDATE_TID.
|
||||
u64 upp_hash; ///< SHA-256 checksum for the update partition.
|
||||
u64 upp_id; ///< Must match GAMECARD_UPDATE_TID.
|
||||
u8 reserved_2[0x38];
|
||||
} GameCardHeaderEncryptedArea;
|
||||
} GameCardInfo;
|
||||
|
||||
NXDT_ASSERT(GameCardHeaderEncryptedArea, 0x70);
|
||||
NXDT_ASSERT(GameCardInfo, 0x70);
|
||||
|
||||
/// Placed after the `GameCardKeyArea` section.
|
||||
typedef struct {
|
||||
u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the header.
|
||||
u32 magic; ///< "HEAD".
|
||||
u32 secure_area_start_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks.
|
||||
u32 backup_area_start_address; ///< Always 0xFFFFFFFF.
|
||||
u32 rom_area_start_page_address; ///< Expressed in GAMECARD_PAGE_SIZE units.
|
||||
u32 backup_area_start_page_address; ///< Always 0xFFFFFFFF.
|
||||
GameCardKeyIndex key_index;
|
||||
u8 rom_size; ///< GameCardRomSize.
|
||||
u8 header_version; ///< Always 0.
|
||||
u8 flags; ///< GameCardFlags.
|
||||
u64 package_id;
|
||||
u32 valid_data_end_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks.
|
||||
u64 package_id; ///< Used for challenge–response authentication.
|
||||
u32 valid_data_end_address; ///< Expressed in GAMECARD_PAGE_SIZE units.
|
||||
u8 reserved[0x4];
|
||||
u8 iv[0x10];
|
||||
u64 partition_fs_header_address; ///< Root HFS0 header offset.
|
||||
u64 partition_fs_header_size; ///< Root HFS0 header size.
|
||||
u64 partition_fs_header_address; ///< Root Hash File System header offset.
|
||||
u64 partition_fs_header_size; ///< Root Hash File System header size.
|
||||
u8 partition_fs_header_hash[SHA256_HASH_SIZE];
|
||||
u8 initial_data_hash[SHA256_HASH_SIZE];
|
||||
u32 sel_sec; ///< GameCardSelSec.
|
||||
u32 sel_t1_key; ///< Always 2.
|
||||
u32 sel_key; ///> Always 0.
|
||||
u32 normal_area_end_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks.
|
||||
GameCardHeaderEncryptedArea encrypted_area;
|
||||
u32 lim_area; ///< Expressed in GAMECARD_PAGE_SIZE units.
|
||||
GameCardInfo card_info;
|
||||
} GameCardHeader;
|
||||
|
||||
NXDT_ASSERT(GameCardHeader, 0x200);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define GAMECARD_ACCESS_WAIT_TIME 3 /* Seconds. */
|
||||
|
||||
#define GAMECARD_UNUSED_AREA_BLOCK_SIZE 0x24
|
||||
#define GAMECARD_UNUSED_AREA_SIZE(x) (((x) / GAMECARD_MEDIA_UNIT_SIZE) * GAMECARD_UNUSED_AREA_BLOCK_SIZE)
|
||||
#define GAMECARD_UNUSED_AREA_SIZE(x) (((x) / GAMECARD_PAGE_SIZE) * GAMECARD_UNUSED_AREA_BLOCK_SIZE)
|
||||
|
||||
#define GAMECARD_STORAGE_AREA_NAME(x) ((x) == GameCardStorageArea_Normal ? "normal" : ((x) == GameCardStorageArea_Secure ? "secure" : "none"))
|
||||
|
||||
|
@ -322,7 +322,7 @@ bool gamecardGetTrimmedSize(u64 *out)
|
|||
{
|
||||
mutexLock(&g_gameCardMutex);
|
||||
bool ret = (g_gameCardInserted && g_gameCardInfoLoaded && out);
|
||||
if (ret) *out = (sizeof(GameCardHeader) + GAMECARD_MEDIA_UNIT_OFFSET(g_gameCardHeader.valid_data_end_address));
|
||||
if (ret) *out = (sizeof(GameCardHeader) + GAMECARD_PAGE_OFFSET(g_gameCardHeader.valid_data_end_address));
|
||||
mutexUnlock(&g_gameCardMutex);
|
||||
return ret;
|
||||
}
|
||||
|
@ -840,9 +840,9 @@ static bool gamecardReadStorageArea(void *out, u64 read_size, u64 offset, bool l
|
|||
/* Calculate appropiate storage area offset and retrieve the right storage area pointer. */
|
||||
u64 base_offset = (area == GameCardStorageArea_Normal ? offset : (offset - g_gameCardStorageNormalAreaSize));
|
||||
|
||||
if (!(base_offset % GAMECARD_MEDIA_UNIT_SIZE) && !(read_size % GAMECARD_MEDIA_UNIT_SIZE))
|
||||
if (!(base_offset % GAMECARD_PAGE_SIZE) && !(read_size % GAMECARD_PAGE_SIZE))
|
||||
{
|
||||
/* Optimization for reads that are already aligned to a GAMECARD_MEDIA_UNIT_SIZE boundary. */
|
||||
/* Optimization for reads that are already aligned to a GAMECARD_PAGE_SIZE boundary. */
|
||||
rc = fsStorageRead(&g_gameCardStorage, base_offset, out_u8, read_size);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
|
@ -853,8 +853,8 @@ static bool gamecardReadStorageArea(void *out, u64 read_size, u64 offset, bool l
|
|||
success = true;
|
||||
} else {
|
||||
/* Fix offset and/or size to avoid unaligned reads. */
|
||||
u64 block_start_offset = ALIGN_DOWN(base_offset, GAMECARD_MEDIA_UNIT_SIZE);
|
||||
u64 block_end_offset = ALIGN_UP(base_offset + read_size, GAMECARD_MEDIA_UNIT_SIZE);
|
||||
u64 block_start_offset = ALIGN_DOWN(base_offset, GAMECARD_PAGE_SIZE);
|
||||
u64 block_end_offset = ALIGN_UP(base_offset + read_size, GAMECARD_PAGE_SIZE);
|
||||
u64 block_size = (block_end_offset - block_start_offset);
|
||||
|
||||
u64 data_start_offset = (base_offset - block_start_offset);
|
||||
|
@ -976,8 +976,8 @@ static HashFileSystemContext *gamecardInitializeHashFileSystemContext(const char
|
|||
|
||||
bool success = false, dump_fs_header = false;
|
||||
|
||||
if ((name && !*name) || offset < (GAMECARD_CERTIFICATE_OFFSET + sizeof(FsGameCardCertificate)) || !IS_ALIGNED(offset, GAMECARD_MEDIA_UNIT_SIZE) || \
|
||||
(size && (!IS_ALIGNED(size, GAMECARD_MEDIA_UNIT_SIZE) || (offset + size) > g_gameCardStorageTotalSize)))
|
||||
if ((name && !*name) || offset < (GAMECARD_CERTIFICATE_OFFSET + sizeof(FsGameCardCertificate)) || !IS_ALIGNED(offset, GAMECARD_PAGE_SIZE) || \
|
||||
(size && (!IS_ALIGNED(size, GAMECARD_PAGE_SIZE) || (offset + size) > g_gameCardStorageTotalSize)))
|
||||
{
|
||||
LOG_MSG("Invalid parameters!");
|
||||
goto end;
|
||||
|
@ -1039,7 +1039,7 @@ static HashFileSystemContext *gamecardInitializeHashFileSystemContext(const char
|
|||
|
||||
/* Calculate full Hash FS header size. */
|
||||
fs_ctx->header_size = (sizeof(HashFileSystemHeader) + (fs_header.entry_count * sizeof(HashFileSystemEntry)) + fs_header.name_table_size);
|
||||
fs_ctx->header_size = ALIGN_UP(fs_ctx->header_size, GAMECARD_MEDIA_UNIT_SIZE);
|
||||
fs_ctx->header_size = ALIGN_UP(fs_ctx->header_size, GAMECARD_PAGE_SIZE);
|
||||
|
||||
/* Allocate memory for the full Hash FS header. */
|
||||
fs_ctx->header = calloc(fs_ctx->header_size, sizeof(u8));
|
||||
|
|
Loading…
Reference in a new issue