Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion arm9/source/gamecart/gamecart.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef struct {
u8 unused[0x4000 + 0x8000 - PRIV_HDR_SIZE]; // 0xFF
u32 cart_type;
u32 cart_id;
u32 cart_id2;
u64 cart_size;
u64 data_size;
u32 save_size;
Expand All @@ -37,6 +38,7 @@ typedef struct {
u8 modcrypt_area[0x4000];
u32 cart_type;
u32 cart_id;
u32 cart_id2; // meaningless on TWL
u64 cart_size;
u64 data_size;
u32 save_size;
Expand Down Expand Up @@ -190,6 +192,7 @@ u32 InitCartRead(CartData* cdata) {
// init, NCCH header
static u32 sec_keys[4];
u8* ncch_header = cdata->header + 0x1000;
cdata->cart_id2 = Cart_GetID2();
CTR_CmdReadHeader(ncch_header);
Cart_Secure_Init((u32*) (void*) ncch_header, sec_keys);

Expand All @@ -214,7 +217,7 @@ u32 InitCartRead(CartData* cdata) {
u8* priv_header = cdata->header + 0x4000;
CTR_CmdReadUniqueID(priv_header);
memcpy(priv_header + 0x40, &(cdata->cart_id), 4);
memset(priv_header + 0x44, 0x00, 4);
memcpy(priv_header + 0x44, &(cdata->cart_id2), 4);
memset(priv_header + 0x48, 0xFF, 8);

// save data
Expand Down
1 change: 1 addition & 0 deletions arm9/source/gamecart/gamecart.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef struct {
u8 storage[0x8000]; // encrypted secure area + modcrypt area / unused
u32 cart_type;
u32 cart_id;
u32 cart_id2; // crypto type, some special dev stuff, normally all-0 for retail
u64 cart_size;
u64 data_size;
u32 save_size;
Expand Down
17 changes: 11 additions & 6 deletions arm9/source/gamecart/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
u32 CartID = 0xFFFFFFFFu;
u32 CartType = 0;

static u32 A0_Response = 0xFFFFFFFFu;
static u32 CartID2 = 0xFFFFFFFFu;
static u32 rand1 = 0;
static u32 rand2 = 0;

Expand Down Expand Up @@ -85,6 +85,11 @@ u32 Cart_GetID(void)
return CartID;
}

u32 Cart_GetID2(void)
{
return CartID2;
}

void Cart_Init(void)
{
ResetCardSlot(); //Seems to reset the cart slot?
Expand All @@ -95,8 +100,8 @@ void Cart_Init(void)

// 3ds
if (CartID & 0x10000000) {
u32 unknowna0_cmd[2] = { 0xA0000000, 0x00000000 };
NTR_SendCommand(unknowna0_cmd, 0x4, 0, &A0_Response);
u32 getid2_cmd[2] = { 0xA0000000, 0x00000000 };
NTR_SendCommand(getid2_cmd, 0x4, 0, &CartID2);

NTR_CmdEnter16ByteMode();
SwitchToCTRCARD();
Expand All @@ -120,7 +125,7 @@ static u8 card_aes(u32 *out, u32 *buff, size_t size) { // note size param ignore

//const u8 is_dev_unit = *(vu8*)0x10010010;
//if(is_dev_unit) //Dev unit
const u8 is_dev_cart = (A0_Response&3)==3;
const u8 is_dev_cart = (CartID2&3)==3;
if(is_dev_cart) //Dev unit
{
AES_SetKeyControl(0x11);
Expand Down Expand Up @@ -180,7 +185,7 @@ void Cart_Secure_Init(u32 *buf, u32 *out)

ARM_WaitCycles(0xF0000 * 8);

CTR_SetSecKey(A0_Response);
CTR_SetSecKey(CartID2);
CTR_SetSecSeed(out, true);

rand1 = 0x42434445;//*((vu32*)0x10011000);
Expand All @@ -200,7 +205,7 @@ void Cart_Secure_Init(u32 *buf, u32 *out)
const u32 A3_cmd[4] = { 0xA3000000, 0x00000000, rand1, rand2 };
CTR_SendCommand(A3_cmd, 4, 1, 0x701002C, &test2);

if(test==CartID && test2==A0_Response)
if(test==CartID && test2==CartID2)
{
const u32 C5_cmd[4] = { 0xC5000000, 0x00000000, rand1, rand2 };
CTR_SendCommand(C5_cmd, 0, 1, 0x100002C, NULL);
Expand Down
1 change: 1 addition & 0 deletions arm9/source/gamecart/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
void Cart_Init(void);
int Cart_IsInserted(void);
u32 Cart_GetID(void);
u32 Cart_GetID2(void);
void Cart_Secure_Init(u32* buf, u32* out);
void Cart_Dummy(void);