* base for potentially re-encrypting modcrypt, doesn't seem to be required? but can also serve to decrypt it
* revise SD IRQ behavior (fixing potential hang when loading DS games)
This commit is contained in:
parent
9c1ea0e539
commit
dcda848cdf
|
@ -398,7 +398,7 @@ void Update()
|
|||
{
|
||||
Ctx.Iv[13] = 0x00;
|
||||
Ctx.Iv[14] = 0x00;
|
||||
Ctx.Iv[15] = 0x00;_printhex(Ctx.Iv, 16);
|
||||
Ctx.Iv[15] = 0x00;
|
||||
AES_CTR_xcrypt_buffer(&Ctx, CurMAC, 16);
|
||||
|
||||
//printf("FINAL MAC: "); _printhexR(CurMAC, 16);
|
||||
|
@ -505,4 +505,63 @@ void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// utility
|
||||
|
||||
void GetModcryptKey(u8* romheader, u8* key)
|
||||
{
|
||||
if ((romheader[0x01C] & 0x04) || (romheader[0x1BF] & 0x80))
|
||||
{
|
||||
// dev key
|
||||
memcpy(key, &romheader[0x000], 16);
|
||||
return;
|
||||
}
|
||||
|
||||
u8 oldkeys[16*3];
|
||||
memcpy(&oldkeys[16*0], KeyX[0], 16);
|
||||
memcpy(&oldkeys[16*1], KeyY[0], 16);
|
||||
memcpy(&oldkeys[16*2], KeyNormal[0], 16);
|
||||
|
||||
KeyX[0][8] = romheader[0x00C];
|
||||
KeyX[0][9] = romheader[0x00D];
|
||||
KeyX[0][10] = romheader[0x00E];
|
||||
KeyX[0][11] = romheader[0x00F];
|
||||
KeyX[0][12] = romheader[0x00F];
|
||||
KeyX[0][13] = romheader[0x00E];
|
||||
KeyX[0][14] = romheader[0x00D];
|
||||
KeyX[0][15] = romheader[0x00C];
|
||||
|
||||
memcpy(KeyY[0], &romheader[0x350], 16);
|
||||
|
||||
DeriveNormalKey(0);
|
||||
memcpy(key, KeyNormal[0], 16);
|
||||
|
||||
memcpy(KeyX[0], &oldkeys[16*0], 16);
|
||||
memcpy(KeyY[0], &oldkeys[16*1], 16);
|
||||
memcpy(KeyNormal[0], &oldkeys[16*2], 16);
|
||||
}
|
||||
|
||||
void ApplyModcrypt(u8* data, u32 len, u8* key, u8* iv)
|
||||
{
|
||||
u8 key_rev[16], iv_rev[16];
|
||||
u8 data_rev[16];
|
||||
u8 oldkeys[16*2];
|
||||
memcpy(&oldkeys[16*0], Ctx.RoundKey, 16);
|
||||
memcpy(&oldkeys[16*1], Ctx.Iv, 16);
|
||||
|
||||
Swap16(key_rev, key);
|
||||
Swap16(iv_rev, iv);
|
||||
AES_init_ctx_iv(&Ctx, key_rev, iv_rev);
|
||||
|
||||
for (u32 i = 0; i < len; i += 16)
|
||||
{
|
||||
Swap16(data_rev, &data[i]);
|
||||
AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16);
|
||||
Swap16(&data[i], data_rev);
|
||||
}
|
||||
|
||||
memcpy(Ctx.RoundKey, &oldkeys[16*0], 16);
|
||||
memcpy(Ctx.Iv, &oldkeys[16*1], 16);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ void WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask);
|
|||
void WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask);
|
||||
void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask);
|
||||
|
||||
void GetModcryptKey(u8* romheader, u8* key);
|
||||
void ApplyModcrypt(u8* data, u32 len, u8* key, u8* iv);
|
||||
|
||||
}
|
||||
|
||||
#endif // DSI_AES_H
|
||||
|
|
|
@ -149,6 +149,15 @@ void DSi_SDHost::SetIRQ(u32 irq)
|
|||
if (irq == 24 || irq == 25) UpdateData32IRQ();
|
||||
}
|
||||
|
||||
void DSi_SDHost::UpdateIRQ(u32 oldmask)
|
||||
{
|
||||
u32 oldflags = IRQStatus & ~oldmask;
|
||||
u32 newflags = IRQStatus & ~IRQMask;
|
||||
|
||||
if ((oldflags == 0) && (newflags != 0))
|
||||
NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC);
|
||||
}
|
||||
|
||||
void DSi_SDHost::SetCardIRQ()
|
||||
{
|
||||
if (!(CardIRQCtl & (1<<0))) return;
|
||||
|
@ -424,7 +433,7 @@ u32 DSi_SDHost::ReadFIFO32()
|
|||
|
||||
return ret;
|
||||
}
|
||||
int morp = 0;
|
||||
|
||||
void DSi_SDHost::Write(u32 addr, u16 val)
|
||||
{
|
||||
//if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
|
||||
|
@ -464,11 +473,21 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||
|
||||
case 0x01C: IRQStatus &= (val | 0xFFFF0000); return;
|
||||
case 0x01E: IRQStatus &= ((val << 16) | 0xFFFF); return;
|
||||
case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return;
|
||||
case 0x020:
|
||||
{
|
||||
u32 oldmask = IRQMask;
|
||||
IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D);
|
||||
UpdateIRQ(oldmask);
|
||||
}
|
||||
return;
|
||||
case 0x022:
|
||||
IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16);
|
||||
if (!DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(24); // checkme
|
||||
if (DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(25); // checkme
|
||||
{
|
||||
u32 oldmask = IRQMask;
|
||||
IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16);
|
||||
UpdateIRQ(oldmask);
|
||||
if (!DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(24); // checkme
|
||||
if (DataFIFO[CurFIFO]->IsEmpty()) SetIRQ(25); // checkme
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x024: SDClock = val & 0x03FF; return;
|
||||
|
|
|
@ -84,6 +84,7 @@ private:
|
|||
void UpdateData32IRQ();
|
||||
void ClearIRQ(u32 irq);
|
||||
void SetIRQ(u32 irq);
|
||||
void UpdateIRQ(u32 oldmask);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "NDSCart.h"
|
||||
#include "ARM.h"
|
||||
#include "CRC32.h"
|
||||
#include "DSi_AES.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
|
@ -599,6 +600,15 @@ void Key2_Encrypt(u8* data, u32 len)
|
|||
}
|
||||
|
||||
|
||||
void ApplyModcrypt(u32 addr, u32 len, u8* iv)
|
||||
{return;
|
||||
u8 key[16];
|
||||
|
||||
DSi_AES::GetModcryptKey(&CartROM[0], key);
|
||||
DSi_AES::ApplyModcrypt(&CartROM[addr], len, key, iv);
|
||||
}
|
||||
|
||||
|
||||
bool Init()
|
||||
{
|
||||
if (!NDSCart_SRAM::Init()) return false;
|
||||
|
@ -980,6 +990,19 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
|||
CartIsHomebrew = true;
|
||||
}
|
||||
|
||||
// re-encrypt modcrypt areas if needed
|
||||
// TODO: somehow detect whether those are already encrypted
|
||||
if (true)
|
||||
{
|
||||
u32 mod1 = *(u32*)&CartROM[0x220];
|
||||
u32 mod2 = *(u32*)&CartROM[0x228];
|
||||
|
||||
printf("Re-encrypting modcrypt areas: %08X, %08X\n", mod1, mod2);
|
||||
|
||||
if (mod1) ApplyModcrypt(mod1, *(u32*)&CartROM[0x224], &CartROM[0x300]);
|
||||
if (mod2) ApplyModcrypt(mod2, *(u32*)&CartROM[0x22C], &CartROM[0x314]);
|
||||
}
|
||||
|
||||
|
||||
// save
|
||||
printf("Save file: %s\n", sram);
|
||||
|
|
Loading…
Reference in New Issue