diff --git a/source/gamecard.c b/source/gamecard.c index 28d323f..dd0f29d 100644 --- a/source/gamecard.c +++ b/source/gamecard.c @@ -28,8 +28,8 @@ #define GAMECARD_ACCESS_WAIT_TIME 3 /* Seconds. */ -#define GAMECARD_ECC_BLOCK_SIZE 0x200 -#define GAMECARD_ECC_DATA_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_STORAGE_AREA_NAME(x) ((x) == GameCardStorageArea_Normal ? "normal" : ((x) == GameCardStorageArea_Secure ? "secure" : "none")) @@ -323,7 +323,7 @@ bool gamecardGetTrimmedSize(u64 *out) { mutexLock(&g_gamecardMutex); bool ret = (g_gameCardInserted && g_gameCardInfoLoaded && out); - if (ret) *out = (sizeof(GameCardHeader) + ((u64)g_gameCardHeader.valid_data_end_address * GAMECARD_MEDIA_UNIT_SIZE)); + if (ret) *out = (sizeof(GameCardHeader) + GAMECARD_MEDIA_UNIT_OFFSET(g_gameCardHeader.valid_data_end_address)); mutexUnlock(&g_gamecardMutex); return ret; } @@ -619,7 +619,7 @@ static void gamecardLoadInfo(void) { /* The total size for the secure storage area is maxed out under SX OS. */ /* Let's try to calculate it manually. */ - g_gameCardStorageSecureAreaSize = ((g_gameCardCapacity - ((g_gameCardCapacity / GAMECARD_ECC_BLOCK_SIZE) * GAMECARD_ECC_DATA_SIZE)) - g_gameCardStorageNormalAreaSize); + g_gameCardStorageSecureAreaSize = (g_gameCardCapacity - (g_gameCardStorageNormalAreaSize + GAMECARD_UNUSED_AREA_SIZE(g_gameCardCapacity))); } /* Allocate memory for the root hash FS header. */ diff --git a/source/gamecard.h b/source/gamecard.h index 67f6f65..d91c6e6 100644 --- a/source/gamecard.h +++ b/source/gamecard.h @@ -29,6 +29,7 @@ #define GAMECARD_CERT_MAGIC 0x43455254 /* "CERT". */ #define GAMECARD_MEDIA_UNIT_SIZE 0x200 +#define GAMECARD_MEDIA_UNIT_OFFSET(x) ((u64)(x) * GAMECARD_MEDIA_UNIT_SIZE) #define GAMECARD_UPDATE_TID (u64)0x0100000000000816 @@ -57,10 +58,10 @@ typedef struct { u8 reserved[0xCF0]; } GameCardTitleKey; -/// Encrypted using RSA-2048-OAEP. Assumed to be all zeroes in retail gamecards. +/// Encrypted using RSA-2048-OAEP and a private OAEP key from AuthoringTool. Assumed to be all zeroes in retail gamecards. typedef struct { - u8 titlekey_encryption_key[0x10]; ///< Used as the AES-128-CTR key for the `GameCardTitleKey` section. - u8 titlekey_encryption_iv[0x10]; ///< Used as the AES-128-CTR IV/counter for the `GameCardTitleKey` section. + u8 titlekey_encryption_key[0x10]; ///< Used as the AES-128-CTR key for the `GameCardTitleKey` section. Randomly generated during XCI creation by AuthoringTool. + u8 titlekey_encryption_iv[0x10]; ///< Used as the AES-128-CTR IV/counter for the `GameCardTitleKey` section. Randomly generated during XCI creation by AuthoringTool. u8 reserved[0xE0]; } GameCardTitleKeyEncryption;