1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-11-26 20:22:17 +00:00

Match changes to the XCI page in Switchbrew.

This commit is contained in:
Pablo Curiel 2021-04-05 20:40:57 -04:00
parent 86dbe3ffd8
commit 460bee888b
2 changed files with 30 additions and 30 deletions

View file

@ -33,8 +33,8 @@ extern "C" {
#define GAMECARD_HEAD_MAGIC 0x48454144 /* "HEAD". */ #define GAMECARD_HEAD_MAGIC 0x48454144 /* "HEAD". */
#define GAMECARD_MEDIA_UNIT_SIZE 0x200 #define GAMECARD_PAGE_SIZE 0x200
#define GAMECARD_MEDIA_UNIT_OFFSET(x) ((u64)(x) * GAMECARD_MEDIA_UNIT_SIZE) #define GAMECARD_PAGE_OFFSET(x) ((u64)(x) * GAMECARD_PAGE_SIZE)
#define GAMECARD_UPDATE_TID SYSTEM_UPDATE_TID #define GAMECARD_UPDATE_TID SYSTEM_UPDATE_TID
@ -123,8 +123,8 @@ typedef enum {
typedef enum { typedef enum {
GameCardFwVersion_ForDev = 0, GameCardFwVersion_ForDev = 0,
GameCardFwVersion_ForProd = BIT(0), GameCardFwVersion_ForProd = BIT(0),
GameCardFwVersion_ForProdSince400NUP = BIT(1), ///< cup_version >= 268435456 (4.0.0-0.0) in GameCardHeaderEncryptedArea. GameCardFwVersion_ForProdSince400NUP = BIT(1), ///< upp_version >= 268435456 (4.0.0-0.0) in GameCardInfo.
GameCardFwVersion_ForProdSince1100NUP = BIT(2) ///< cup_version >= 738197504 (11.0.0-0.0) in GameCardHeaderEncryptedArea. GameCardFwVersion_ForProdSince1100NUP = BIT(2) ///< upp_version >= 738197504 (11.0.0-0.0) in GameCardInfo.
} GameCardFwVersion; } GameCardFwVersion;
typedef enum { typedef enum {
@ -148,40 +148,40 @@ typedef struct {
u32 wait_2_time_read; ///< Always 0. u32 wait_2_time_read; ///< Always 0.
u32 wait_1_time_write; ///< Always 0. u32 wait_1_time_write; ///< Always 0.
u32 wait_2_time_write; ///< Always 0. u32 wait_2_time_write; ///< Always 0.
VersionType2 fw_mode; VersionType2 fw_mode; ///< Current SdkAddonVersion.
VersionType1 cup_version; VersionType1 upp_version; ///< Bundled system update version.
u8 compatibility_type; ///< GameCardCompatibilityType. u8 compatibility_type; ///< GameCardCompatibilityType.
u8 reserved_1[0x3]; u8 reserved_1[0x3];
u64 cup_hash; u64 upp_hash; ///< SHA-256 checksum for the update partition.
u64 cup_id; ///< Must match GAMECARD_UPDATE_TID. u64 upp_id; ///< Must match GAMECARD_UPDATE_TID.
u8 reserved_2[0x38]; u8 reserved_2[0x38];
} GameCardHeaderEncryptedArea; } GameCardInfo;
NXDT_ASSERT(GameCardHeaderEncryptedArea, 0x70); NXDT_ASSERT(GameCardInfo, 0x70);
/// Placed after the `GameCardKeyArea` section. /// Placed after the `GameCardKeyArea` section.
typedef struct { typedef struct {
u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the header. u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the header.
u32 magic; ///< "HEAD". u32 magic; ///< "HEAD".
u32 secure_area_start_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks. u32 rom_area_start_page_address; ///< Expressed in GAMECARD_PAGE_SIZE units.
u32 backup_area_start_address; ///< Always 0xFFFFFFFF. u32 backup_area_start_page_address; ///< Always 0xFFFFFFFF.
GameCardKeyIndex key_index; GameCardKeyIndex key_index;
u8 rom_size; ///< GameCardRomSize. u8 rom_size; ///< GameCardRomSize.
u8 header_version; ///< Always 0. u8 header_version; ///< Always 0.
u8 flags; ///< GameCardFlags. u8 flags; ///< GameCardFlags.
u64 package_id; u64 package_id; ///< Used for challengeresponse authentication.
u32 valid_data_end_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks. u32 valid_data_end_address; ///< Expressed in GAMECARD_PAGE_SIZE units.
u8 reserved[0x4]; u8 reserved[0x4];
u8 iv[0x10]; u8 iv[0x10];
u64 partition_fs_header_address; ///< Root HFS0 header offset. u64 partition_fs_header_address; ///< Root Hash File System header offset.
u64 partition_fs_header_size; ///< Root HFS0 header size. u64 partition_fs_header_size; ///< Root Hash File System header size.
u8 partition_fs_header_hash[SHA256_HASH_SIZE]; u8 partition_fs_header_hash[SHA256_HASH_SIZE];
u8 initial_data_hash[SHA256_HASH_SIZE]; u8 initial_data_hash[SHA256_HASH_SIZE];
u32 sel_sec; ///< GameCardSelSec. u32 sel_sec; ///< GameCardSelSec.
u32 sel_t1_key; ///< Always 2. u32 sel_t1_key; ///< Always 2.
u32 sel_key; ///> Always 0. u32 sel_key; ///> Always 0.
u32 normal_area_end_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks. u32 lim_area; ///< Expressed in GAMECARD_PAGE_SIZE units.
GameCardHeaderEncryptedArea encrypted_area; GameCardInfo card_info;
} GameCardHeader; } GameCardHeader;
NXDT_ASSERT(GameCardHeader, 0x200); NXDT_ASSERT(GameCardHeader, 0x200);

View file

@ -30,7 +30,7 @@
#define GAMECARD_ACCESS_WAIT_TIME 3 /* Seconds. */ #define GAMECARD_ACCESS_WAIT_TIME 3 /* Seconds. */
#define GAMECARD_UNUSED_AREA_BLOCK_SIZE 0x24 #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")) #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); mutexLock(&g_gameCardMutex);
bool ret = (g_gameCardInserted && g_gameCardInfoLoaded && out); 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); mutexUnlock(&g_gameCardMutex);
return ret; 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. */ /* Calculate appropiate storage area offset and retrieve the right storage area pointer. */
u64 base_offset = (area == GameCardStorageArea_Normal ? offset : (offset - g_gameCardStorageNormalAreaSize)); 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); rc = fsStorageRead(&g_gameCardStorage, base_offset, out_u8, read_size);
if (R_FAILED(rc)) if (R_FAILED(rc))
{ {
@ -853,8 +853,8 @@ static bool gamecardReadStorageArea(void *out, u64 read_size, u64 offset, bool l
success = true; success = true;
} else { } else {
/* Fix offset and/or size to avoid unaligned reads. */ /* Fix offset and/or size to avoid unaligned reads. */
u64 block_start_offset = ALIGN_DOWN(base_offset, 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_MEDIA_UNIT_SIZE); u64 block_end_offset = ALIGN_UP(base_offset + read_size, GAMECARD_PAGE_SIZE);
u64 block_size = (block_end_offset - block_start_offset); u64 block_size = (block_end_offset - block_start_offset);
u64 data_start_offset = (base_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; bool success = false, dump_fs_header = false;
if ((name && !*name) || offset < (GAMECARD_CERTIFICATE_OFFSET + sizeof(FsGameCardCertificate)) || !IS_ALIGNED(offset, GAMECARD_MEDIA_UNIT_SIZE) || \ if ((name && !*name) || offset < (GAMECARD_CERTIFICATE_OFFSET + sizeof(FsGameCardCertificate)) || !IS_ALIGNED(offset, GAMECARD_PAGE_SIZE) || \
(size && (!IS_ALIGNED(size, GAMECARD_MEDIA_UNIT_SIZE) || (offset + size) > g_gameCardStorageTotalSize))) (size && (!IS_ALIGNED(size, GAMECARD_PAGE_SIZE) || (offset + size) > g_gameCardStorageTotalSize)))
{ {
LOG_MSG("Invalid parameters!"); LOG_MSG("Invalid parameters!");
goto end; goto end;
@ -1039,7 +1039,7 @@ static HashFileSystemContext *gamecardInitializeHashFileSystemContext(const char
/* Calculate full Hash FS header size. */ /* 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 = (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. */ /* Allocate memory for the full Hash FS header. */
fs_ctx->header = calloc(fs_ctx->header_size, sizeof(u8)); fs_ctx->header = calloc(fs_ctx->header_size, sizeof(u8));