diff --git a/src/DSi.cpp b/src/DSi.cpp index bdbe7f5b..9ae7d93f 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -79,6 +79,8 @@ std::unique_ptr NANDImage; DSi_SDHost* SDMMC; DSi_SDHost* SDIO; +DSi_AES* AES; + // FIXME: these currently have no effect (and aren't stored in a savestate) // ... not that they matter all that much u8 GPIO_Data; @@ -102,7 +104,6 @@ bool Init() if (!DSi_I2C::Init()) return false; if (!DSi_CamModule::Init()) return false; - if (!DSi_AES::Init()) return false; if (!DSi_DSP::Init()) return false; NDMAs[0] = new DSi_NDMA(0, 0); @@ -117,6 +118,8 @@ bool Init() SDMMC = new DSi_SDHost(0); SDIO = new DSi_SDHost(1); + AES = new DSi_AES(); + return true; } @@ -134,7 +137,6 @@ void DeInit() DSi_I2C::DeInit(); DSi_CamModule::DeInit(); - DSi_AES::DeInit(); DSi_DSP::DeInit(); for (int i = 0; i < 8; i++) @@ -143,10 +145,10 @@ void DeInit() NDMAs[i] = nullptr; } - delete SDMMC; - SDMMC = nullptr; - delete SDIO; - SDIO = nullptr; + delete SDMMC; SDMMC = nullptr; + delete SDIO; SDIO = nullptr; + + delete AES; AES = nullptr; NANDImage = nullptr; // The NANDImage is cleaned up (and its underlying file closed) @@ -176,7 +178,7 @@ void Reset() SDMMC->Reset(); SDIO->Reset(); - DSi_AES::Reset(); + AES->Reset(); if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) { @@ -282,7 +284,7 @@ void DoSavestate(Savestate* file) for (int i = 0; i < 8; i++) NDMAs[i]->DoSavestate(file); - DSi_AES::DoSavestate(file); + AES->DoSavestate(file); DSi_CamModule::DoSavestate(file); DSi_DSP::DoSavestate(file); DSi_I2C::DoSavestate(file); @@ -706,7 +708,7 @@ void SoftReset() SDMMC->Reset(); SDIO->Reset(); - DSi_AES::Reset(); + AES->Reset(); if (Platform::GetConfigBool(Platform::DSi_FullBIOSBoot)) { @@ -2839,8 +2841,8 @@ u32 ARM7IORead32(u32 addr) case 0x0400416C: return NDMAs[7]->FillData; case 0x04004170: return NDMAs[7]->Cnt; - case 0x04004400: return DSi_AES::ReadCnt(); - case 0x0400440C: return DSi_AES::ReadOutputFIFO(); + case 0x04004400: return AES->ReadCnt(); + case 0x0400440C: return AES->ReadOutputFIFO(); case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() & 0xFFFFFFFF; case 0x04004D04: if (SCFG_BIOS & (1<<10)) return 0; return NANDImage->GetConsoleID() >> 32; @@ -2929,7 +2931,7 @@ void ARM7IOWrite8(u32 addr, u8 val) u32 shift = (addr&3)*8; addr -= 0x04004420; addr &= ~3; - DSi_AES::WriteIV(addr, (u32)val << shift, 0xFF << shift); + AES->WriteIV(addr, (u32)val << shift, 0xFF << shift); return; } if (addr >= 0x04004430 && addr < 0x04004440) @@ -2937,7 +2939,7 @@ void ARM7IOWrite8(u32 addr, u8 val) u32 shift = (addr&3)*8; addr -= 0x04004430; addr &= ~3; - DSi_AES::WriteMAC(addr, (u32)val << shift, 0xFF << shift); + AES->WriteMAC(addr, (u32)val << shift, 0xFF << shift); return; } if (addr >= 0x04004440 && addr < 0x04004500) @@ -2951,9 +2953,9 @@ void ARM7IOWrite8(u32 addr, u8 val) switch (addr >> 4) { - case 0: DSi_AES::WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; - case 1: DSi_AES::WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; - case 2: DSi_AES::WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; + case 0: AES->WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; + case 1: AES->WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; + case 2: AES->WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFF << shift); return; } } @@ -2999,7 +3001,7 @@ void ARM7IOWrite16(u32 addr, u16 val) return; case 0x04004406: - DSi_AES::WriteBlkCnt(val<<16); + AES->WriteBlkCnt(val<<16); return; case 0x4004700: @@ -3024,7 +3026,7 @@ void ARM7IOWrite16(u32 addr, u16 val) u32 shift = (addr&1)*16; addr -= 0x04004420; addr &= ~1; - DSi_AES::WriteIV(addr, (u32)val << shift, 0xFFFF << shift); + AES->WriteIV(addr, (u32)val << shift, 0xFFFF << shift); return; } if (addr >= 0x04004430 && addr < 0x04004440) @@ -3032,7 +3034,7 @@ void ARM7IOWrite16(u32 addr, u16 val) u32 shift = (addr&1)*16; addr -= 0x04004430; addr &= ~1; - DSi_AES::WriteMAC(addr, (u32)val << shift, 0xFFFF << shift); + AES->WriteMAC(addr, (u32)val << shift, 0xFFFF << shift); return; } if (addr >= 0x04004440 && addr < 0x04004500) @@ -3046,9 +3048,9 @@ void ARM7IOWrite16(u32 addr, u16 val) switch (addr >> 4) { - case 0: DSi_AES::WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; - case 1: DSi_AES::WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; - case 2: DSi_AES::WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; + case 0: AES->WriteKeyNormal(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; + case 1: AES->WriteKeyX(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; + case 2: AES->WriteKeyY(n, addr&0xF, (u32)val << shift, 0xFFFF << shift); return; } } @@ -3146,9 +3148,9 @@ void ARM7IOWrite32(u32 addr, u32 val) case 0x0400416C: NDMAs[7]->FillData = val; return; case 0x04004170: NDMAs[7]->WriteCnt(val); return; - case 0x04004400: DSi_AES::WriteCnt(val); return; - case 0x04004404: DSi_AES::WriteBlkCnt(val); return; - case 0x04004408: DSi_AES::WriteInputFIFO(val); return; + case 0x04004400: AES->WriteCnt(val); return; + case 0x04004404: AES->WriteBlkCnt(val); return; + case 0x04004408: AES->WriteInputFIFO(val); return; case 0x4004700: Log(LogLevel::Debug, "32-Bit SNDExCnt write? %08X %08X\n", val, NDS::ARM7->R[15]); @@ -3159,13 +3161,13 @@ void ARM7IOWrite32(u32 addr, u32 val) if (addr >= 0x04004420 && addr < 0x04004430) { addr -= 0x04004420; - DSi_AES::WriteIV(addr, val, 0xFFFFFFFF); + AES->WriteIV(addr, val, 0xFFFFFFFF); return; } if (addr >= 0x04004430 && addr < 0x04004440) { addr -= 0x04004430; - DSi_AES::WriteMAC(addr, val, 0xFFFFFFFF); + AES->WriteMAC(addr, val, 0xFFFFFFFF); return; } if (addr >= 0x04004440 && addr < 0x04004500) @@ -3176,9 +3178,9 @@ void ARM7IOWrite32(u32 addr, u32 val) switch (addr >> 4) { - case 0: DSi_AES::WriteKeyNormal(n, addr&0xF, val, 0xFFFFFFFF); return; - case 1: DSi_AES::WriteKeyX(n, addr&0xF, val, 0xFFFFFFFF); return; - case 2: DSi_AES::WriteKeyY(n, addr&0xF, val, 0xFFFFFFFF); return; + case 0: AES->WriteKeyNormal(n, addr&0xF, val, 0xFFFFFFFF); return; + case 1: AES->WriteKeyX(n, addr&0xF, val, 0xFFFFFFFF); return; + case 2: AES->WriteKeyY(n, addr&0xF, val, 0xFFFFFFFF); return; } } diff --git a/src/DSi.h b/src/DSi.h index 06ca9798..aa507f55 100644 --- a/src/DSi.h +++ b/src/DSi.h @@ -22,6 +22,8 @@ #include "NDS.h" #include "DSi_SD.h" +class DSi_AES; + namespace DSi_NAND { class NANDImage; @@ -56,6 +58,8 @@ extern u32 NWRAMStart[2][3]; extern u32 NWRAMEnd[2][3]; extern u32 NWRAMMask[2][3]; +extern DSi_AES* AES; + bool Init(); void DeInit(); void Reset(); diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index 1b65dc15..b1d89bd1 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -21,63 +21,11 @@ #include "DSi.h" #include "DSi_NAND.h" #include "DSi_AES.h" -#include "FIFO.h" -#include "tiny-AES-c/aes.hpp" #include "Platform.h" using Platform::Log; using Platform::LogLevel; -namespace DSi_AES -{ - -u32 Cnt; - -u32 BlkCnt; -u32 RemExtra; -u32 RemBlocks; - -bool OutputFlush; - -u32 InputDMASize, OutputDMASize; -u32 AESMode; - -FIFO InputFIFO; -FIFO OutputFIFO; - -u8 IV[16]; - -u8 MAC[16]; - -u8 KeyNormal[4][16]; -u8 KeyX[4][16]; -u8 KeyY[4][16]; - -u8 CurKey[16]; -u8 CurMAC[16]; - -// output MAC for CCM encrypt -u8 OutputMAC[16]; -bool OutputMACDue; - -AES_ctx Ctx; - -void ROL16(u8* val, u32 n) -{ - u32 n_coarse = n >> 3; - u32 n_fine = n & 7; - u8 tmp[16]; - - for (u32 i = 0; i < 16; i++) - { - tmp[i] = val[(i - n_coarse) & 0xF]; - } - - for (u32 i = 0; i < 16; i++) - { - val[i] = (tmp[i] << n_fine) | (tmp[(i - 1) & 0xF] >> (8-n_fine)); - } -} #define _printhex(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); printf("\n"); } #define _printhex2(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); } @@ -86,19 +34,17 @@ void ROL16(u8* val, u32 n) #define _printhex2R(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[((size)-1)-z]); } -bool Init() +DSi_AES::DSi_AES() { const u8 zero[16] = {0}; AES_init_ctx_iv(&Ctx, zero, zero); - - return true; } -void DeInit() +DSi_AES::~DSi_AES() { } -void Reset() +void DSi_AES::Reset() { Cnt = 0; @@ -152,7 +98,7 @@ void Reset() *(u32*)&KeyY[3][8] = 0x202DDD1D; } -void DoSavestate(Savestate* file) +void DSi_AES::DoSavestate(Savestate* file) { file->Section("AESi"); @@ -190,7 +136,7 @@ void DoSavestate(Savestate* file) } -void ProcessBlock_CCM_Extra() +void DSi_AES::ProcessBlock_CCM_Extra() { u8 data[16]; u8 data_rev[16]; @@ -206,7 +152,7 @@ void ProcessBlock_CCM_Extra() AES_ECB_encrypt(&Ctx, CurMAC); } -void ProcessBlock_CCM_Decrypt() +void DSi_AES::ProcessBlock_CCM_Decrypt() { u8 data[16]; u8 data_rev[16]; @@ -234,7 +180,7 @@ void ProcessBlock_CCM_Decrypt() OutputFIFO.Write(*(u32*)&data[12]); } -void ProcessBlock_CCM_Encrypt() +void DSi_AES::ProcessBlock_CCM_Encrypt() { u8 data[16]; u8 data_rev[16]; @@ -262,7 +208,7 @@ void ProcessBlock_CCM_Encrypt() OutputFIFO.Write(*(u32*)&data[12]); } -void ProcessBlock_CTR() +void DSi_AES::ProcessBlock_CTR() { u8 data[16]; u8 data_rev[16]; @@ -287,7 +233,7 @@ void ProcessBlock_CTR() } -u32 ReadCnt() +u32 DSi_AES::ReadCnt() { u32 ret = Cnt; @@ -297,7 +243,7 @@ u32 ReadCnt() return ret; } -void WriteCnt(u32 val) +void DSi_AES::WriteCnt(u32 val) { u32 oldcnt = Cnt; Cnt = val & 0xFC1FF000; @@ -380,12 +326,12 @@ void WriteCnt(u32 val) // val, AESMode, (val >> 26) & 0x3, InputDMASize, OutputDMASize, RemBlocks, BlkCnt); } -void WriteBlkCnt(u32 val) +void DSi_AES::WriteBlkCnt(u32 val) { BlkCnt = val; } -u32 ReadOutputFIFO() +u32 DSi_AES::ReadOutputFIFO() { if (OutputFIFO.IsEmpty()) Log(LogLevel::Warn, "!!! AES OUTPUT FIFO EMPTY\n"); @@ -416,7 +362,7 @@ u32 ReadOutputFIFO() return ret; } -void WriteInputFIFO(u32 val) +void DSi_AES::WriteInputFIFO(u32 val) { // TODO: add some delay to processing @@ -429,7 +375,7 @@ void WriteInputFIFO(u32 val) Update(); } -void CheckInputDMA() +void DSi_AES::CheckInputDMA() { if (RemBlocks == 0 && RemExtra == 0) return; @@ -442,7 +388,7 @@ void CheckInputDMA() Update(); } -void CheckOutputDMA() +void DSi_AES::CheckOutputDMA() { if (OutputFIFO.Level() >= OutputDMASize) { @@ -451,7 +397,7 @@ void CheckOutputDMA() } } -void Update() +void DSi_AES::Update() { if (RemExtra > 0) { @@ -539,7 +485,7 @@ void Update() } -void WriteIV(u32 offset, u32 val, u32 mask) +void DSi_AES::WriteIV(u32 offset, u32 val, u32 mask) { u32 old = *(u32*)&IV[offset]; @@ -548,7 +494,7 @@ void WriteIV(u32 offset, u32 val, u32 mask) //printf("AES: IV: "); _printhex(IV, 16); } -void WriteMAC(u32 offset, u32 val, u32 mask) +void DSi_AES::WriteMAC(u32 offset, u32 val, u32 mask) { u32 old = *(u32*)&MAC[offset]; @@ -557,7 +503,24 @@ void WriteMAC(u32 offset, u32 val, u32 mask) //printf("AES: MAC: "); _printhex(MAC, 16); } -void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey) +void DSi_AES::ROL16(u8* val, u32 n) +{ + u32 n_coarse = n >> 3; + u32 n_fine = n & 7; + u8 tmp[16]; + + for (u32 i = 0; i < 16; i++) + { + tmp[i] = val[(i - n_coarse) & 0xF]; + } + + for (u32 i = 0; i < 16; i++) + { + val[i] = (tmp[i] << n_fine) | (tmp[(i - 1) & 0xF] >> (8-n_fine)); + } +} + +void DSi_AES::DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey) { const u8 key_const[16] = {0xFF, 0xFE, 0xFB, 0x4E, 0x29, 0x59, 0x02, 0x58, 0x2A, 0x68, 0x0F, 0x5F, 0x1A, 0x4F, 0x3E, 0x79}; u8 tmp[16]; @@ -578,7 +541,7 @@ void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey) memcpy(normalkey, tmp, 16); } -void WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask) +void DSi_AES::WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask) { u32 old = *(u32*)&KeyNormal[slot][offset]; @@ -587,7 +550,7 @@ void WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask) //printf("KeyNormal(%d): ", slot); _printhex(KeyNormal[slot], 16); } -void WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask) +void DSi_AES::WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask) { u32 old = *(u32*)&KeyX[slot][offset]; @@ -596,7 +559,7 @@ void WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask) //printf("KeyX(%d): ", slot); _printhex(KeyX[slot], 16); } -void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask) +void DSi_AES::WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask) { u32 old = *(u32*)&KeyY[slot][offset]; @@ -609,5 +572,3 @@ void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask) DeriveNormalKey(KeyX[slot], KeyY[slot], KeyNormal[slot]); } } - -} diff --git a/src/DSi_AES.h b/src/DSi_AES.h index 4030b339..1f1c6bf9 100644 --- a/src/DSi_AES.h +++ b/src/DSi_AES.h @@ -21,6 +21,8 @@ #include "types.h" #include "Savestate.h" +#include "FIFO.h" +#include "tiny-AES-c/aes.hpp" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" @@ -41,35 +43,69 @@ __attribute((always_inline)) static void Bswap128(void* Dst, const void* Src) #endif #pragma GCC diagnostic pop -namespace DSi_AES +class DSi_AES { +public: + DSi_AES(); + ~DSi_AES(); + void Reset(); + void DoSavestate(Savestate* file); -extern u32 Cnt; + u32 ReadCnt(); + void WriteCnt(u32 val); + void WriteBlkCnt(u32 val); -bool Init(); -void DeInit(); -void Reset(); + u32 ReadOutputFIFO(); + void WriteInputFIFO(u32 val); + void CheckInputDMA(); + void CheckOutputDMA(); + void Update(); -void DoSavestate(Savestate* file); + void WriteIV(u32 offset, u32 val, u32 mask); + void WriteMAC(u32 offset, u32 val, u32 mask); + 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); -u32 ReadCnt(); -void WriteCnt(u32 val); -void WriteBlkCnt(u32 val); + static void ROL16(u8* val, u32 n); + static void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey); -u32 ReadOutputFIFO(); -void WriteInputFIFO(u32 val); -void CheckInputDMA(); -void CheckOutputDMA(); -void Update(); +private: + u32 Cnt; -void WriteIV(u32 offset, u32 val, u32 mask); -void WriteMAC(u32 offset, u32 val, u32 mask); -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); + u32 BlkCnt; + u32 RemExtra; + u32 RemBlocks; -void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey); + bool OutputFlush; -} + u32 InputDMASize, OutputDMASize; + u32 AESMode; + + FIFO InputFIFO; + FIFO OutputFIFO; + + u8 IV[16]; + + u8 MAC[16]; + + u8 KeyNormal[4][16]; + u8 KeyX[4][16]; + u8 KeyY[4][16]; + + u8 CurKey[16]; + u8 CurMAC[16]; + + // output MAC for CCM encrypt + u8 OutputMAC[16]; + bool OutputMACDue; + + AES_ctx Ctx; + + void ProcessBlock_CCM_Extra(); + void ProcessBlock_CCM_Decrypt(); + void ProcessBlock_CCM_Encrypt(); + void ProcessBlock_CTR(); +}; #endif // DSI_AES_H diff --git a/src/DSi_NDMA.cpp b/src/DSi_NDMA.cpp index 6c349fac..f3c3745e 100644 --- a/src/DSi_NDMA.cpp +++ b/src/DSi_NDMA.cpp @@ -347,8 +347,8 @@ void DSi_NDMA::Run7() Running = 0; NDS::ResumeCPU(1, 1<<(Num+4)); - DSi_AES::CheckInputDMA(); - DSi_AES::CheckOutputDMA(); + DSi::AES->CheckInputDMA(); + DSi::AES->CheckOutputDMA(); } return; @@ -372,6 +372,6 @@ void DSi_NDMA::Run7() InProgress = false; NDS::ResumeCPU(1, 1<<(Num+4)); - DSi_AES::CheckInputDMA(); - DSi_AES::CheckOutputDMA(); + DSi::AES->CheckInputDMA(); + DSi::AES->CheckOutputDMA(); }