diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index b8bb18edb..1823bb93d 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -19,7 +19,7 @@ libdesmume_a_SOURCES = \ common.cpp common.h \ debug.cpp debug.h \ Disassembler.cpp Disassembler.h \ - emufile.h emufile.cpp emufile_types.h FIFO.cpp FIFO.h \ + emufile.h emufile.cpp emufile_types.h encrypt.h encrypt.cpp FIFO.cpp FIFO.h \ firmware.cpp firmware.h GPU.cpp GPU.h \ fs.h \ GPU_osd.h \ diff --git a/desmume/src/encrypt.cpp b/desmume/src/encrypt.cpp new file mode 100644 index 000000000..bbee6ff08 --- /dev/null +++ b/desmume/src/encrypt.cpp @@ -0,0 +1,111 @@ +/* + Copyright (C) 2009-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#include "encrypt.h" +#include "MMU.h" + +//================================================================================== KEY1 +#define bswap32(val) (((val & 0x000000FF) << 24) | ((val & 0x0000FF00) << 8) | ((val & 0x00FF0000) >> 8) | ((val & 0xFF000000) >> 24)) +#define DWNUM(i) ((i) >> 2) + +void _KEY1::init(u32 idcode, u8 level, u8 modulo) +{ + memcpy(keyBuf, keyBufPtr, 0x1048); + keyCode[0] = idcode; + keyCode[1] = idcode >> 1; + keyCode[2] = idcode << 1; + if (level >= 1) // first apply (always) + applyKeycode(modulo); + if (level >= 2) // second apply (optional) + applyKeycode(modulo); + keyCode[1] <<= 1; + keyCode[2] >>= 1; + if (level >= 3) // third apply (optional) + applyKeycode(modulo); + + printf("keycode1: %08X%08X%08X\n", keyCode[2], keyCode[1], keyCode[0]); +} + +void _KEY1::applyKeycode(u8 modulo) +{ + encrypt(&keyCode[1]); + encrypt(&keyCode[0]); + + u32 scratch[2] = {0}; + + for (u32 i = 0; i <= 0x44; i += 4) // xor with reversed byte-order (bswap) + keyBuf[DWNUM(i)] ^= bswap32(keyCode[DWNUM(i % modulo)]); + + for (u32 i = 0; i <= 0x1040; i += 8) + { + encrypt(scratch); // encrypt S (64bit) by keybuf + keyBuf[DWNUM(i)] = scratch[1]; // write S to keybuf (first upper 32bit) + keyBuf[DWNUM(i+4)] = scratch[0]; // write S to keybuf (then lower 32bit) + } +} + +void _KEY1::decrypt(u32 *ptr) +{ + u32 y = ptr[0]; + u32 x = ptr[1]; + + for (u32 i = 0x11; i >= 0x02; i--) + { + u32 z = keyBuf[i] ^ x; + x = keyBuf[DWNUM(0x048 + (((z >> 24) & 0xFF) << 2))]; + x = keyBuf[DWNUM(0x448 + (((z >> 16) & 0xFF) << 2))] + x; + x = keyBuf[DWNUM(0x848 + (((z >> 8) & 0xFF) << 2))] ^ x; + x = keyBuf[DWNUM(0xC48 + (((z >> 0) & 0xFF) << 2))] + x; + x = y ^ x; + y = z; + } + ptr[0] = x ^ keyBuf[DWNUM(0x04)]; + ptr[1] = y ^ keyBuf[DWNUM(0x00)]; +} + +void _KEY1::encrypt(u32 *ptr) +{ + u32 y = ptr[0]; + u32 x = ptr[1]; + + for (u32 i = 0x00; i <= 0x0F; i++) + { + u32 z = keyBuf[i] ^ x; + x = keyBuf[DWNUM(0x048 + (((z >> 24) & 0xFF) << 2))]; + x = keyBuf[DWNUM(0x448 + (((z >> 16) & 0xFF) << 2))] + x; + x = keyBuf[DWNUM(0x848 + (((z >> 8) & 0xFF) << 2))] ^ x; + x = keyBuf[DWNUM(0xC48 + (((z >> 0) & 0xFF) << 2))] + x; + x = y ^ x; + y = z; + } + + ptr[0] = x ^ keyBuf[DWNUM(0x40)]; + ptr[1] = y ^ keyBuf[DWNUM(0x44)]; +} +#undef DWNUM +#undef bswap32 + +//================================================================================== KEY2 +void _KEY2::applySeed(u8 PROCNUM) +{ + u64 tmp = (MMU_read8(PROCNUM, REG_ENCSEED0H) & 0xFF); + seed0 = MMU_read32(PROCNUM, REG_ENCSEED0L) | (tmp << 32); + tmp = (MMU_read8(PROCNUM, REG_ENCSEED1H) & 0xFF); + seed1 = MMU_read32(PROCNUM, REG_ENCSEED1L) | (tmp << 32); + printf("ARM%c: set KEY2 seed0 to %010llX\n", PROCNUM?'7':'9', seed0); + printf("ARM%c: set KEY2 seed1 to %010llX\n", PROCNUM?'7':'9', seed1); +} diff --git a/desmume/src/encrypt.h b/desmume/src/encrypt.h new file mode 100644 index 000000000..1d776e41d --- /dev/null +++ b/desmume/src/encrypt.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2009-2013 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . +*/ + +#ifndef _ENCRYPT_H_ +#define _ENCRYPT_H_ +#include "types.h" + +struct _KEY1 +{ + _KEY1(u8 *keyBufPtr) + { + if (keyBuf) delete keyBuf; + keyBuf = new u32 [0x1048 / sizeof(u32)]; + memset(keyBuf, 0x00, 0x1048); + memset(&keyCode[0], 0, sizeof(keyCode)); + this->keyBufPtr = keyBufPtr; + } + + ~_KEY1() + { + if (keyBuf) + { + delete keyBuf; + keyBuf = NULL; + } + } + + u32 *keyBuf; + u32 keyCode[3]; + u8 *keyBufPtr; + + void init(u32 idcode, u8 level, u8 modulo); + void applyKeycode(u8 modulo); + void decrypt(u32 *ptr); + void encrypt(u32 *ptr); +}; + +struct _KEY2 +{ + _KEY2() : seed0(0x58C56DE0E8U), + seed1(0x5C879B9B05U) + {} + + u64 seed0; + u64 seed1; + + void applySeed(u8 PROCNUM); +}; + +#endif \ No newline at end of file diff --git a/desmume/src/firmware.cpp b/desmume/src/firmware.cpp index 5b7f4474a..71d43af8d 100644 --- a/desmume/src/firmware.cpp +++ b/desmume/src/firmware.cpp @@ -18,101 +18,9 @@ #include "firmware.h" #include "NDSSystem.h" #include "path.h" +#include "encrypt.h" -#define DWNUM(i) ((i) >> 2) - -bool CFIRMWARE::getKeyBuf() -{ - FILE *file = fopen(CommonSettings.ARM7BIOS, "rb"); - if (!file) return false; - - fseek(file, 0x30, SEEK_SET); - size_t res = fread(keyBuf, 4, 0x412, file); - fclose(file); - return (res == 0x412); -} - -void CFIRMWARE::crypt64BitUp(u32 *ptr) -{ - u32 Y = ptr[0]; - u32 X = ptr[1]; - - for(u32 i = 0x00; i <= 0x0F; i++) - { - u32 Z = (keyBuf[i] ^ X); - X = keyBuf[DWNUM(0x048 + (((Z >> 24) & 0xFF) << 2))]; - X = (keyBuf[DWNUM(0x448 + (((Z >> 16) & 0xFF) << 2))] + X); - X = (keyBuf[DWNUM(0x848 + (((Z >> 8) & 0xFF) << 2))] ^ X); - X = (keyBuf[DWNUM(0xC48 + ((Z & 0xFF) << 2))] + X); - X = (Y ^ X); - Y = Z; - } - - ptr[0] = (X ^ keyBuf[DWNUM(0x40)]); - ptr[1] = (Y ^ keyBuf[DWNUM(0x44)]); -} - -void CFIRMWARE::crypt64BitDown(u32 *ptr) -{ - u32 Y = ptr[0]; - u32 X = ptr[1]; - - for(u32 i = 0x11; i >= 0x02; i--) - { - u32 Z = (keyBuf[i] ^ X); - X = keyBuf[DWNUM(0x048 + (((Z >> 24) & 0xFF) << 2))]; - X = (keyBuf[DWNUM(0x448 + (((Z >> 16) & 0xFF) << 2))] + X); - X = (keyBuf[DWNUM(0x848 + (((Z >> 8) & 0xFF) << 2))] ^ X); - X = (keyBuf[DWNUM(0xC48 + ((Z & 0xFF) << 2))] + X); - X = (Y ^ X); - Y = Z; - } - - ptr[0] = (X ^ keyBuf[DWNUM(0x04)]); - ptr[1] = (Y ^ keyBuf[DWNUM(0x00)]); -} - -#define bswap32(val) (((val & 0x000000FF) << 24) | ((val & 0x0000FF00) << 8) | ((val & 0x00FF0000) >> 8) | ((val & 0xFF000000) >> 24)) -void CFIRMWARE::applyKeycode(u32 modulo) -{ - crypt64BitUp(&keyCode[1]); - crypt64BitUp(&keyCode[0]); - - u32 scratch[2] = {0x00000000, 0x00000000}; - - for(u32 i = 0; i <= 0x44; i += 4) - { - keyBuf[DWNUM(i)] = (keyBuf[DWNUM(i)] ^ bswap32(keyCode[DWNUM(i % modulo)])); - } - - for(u32 i = 0; i <= 0x1040; i += 8) - { - crypt64BitUp(scratch); - keyBuf[DWNUM(i)] = scratch[1]; - keyBuf[DWNUM(i+4)] = scratch[0]; - } -} -#undef bswap32 - -bool CFIRMWARE::initKeycode(u32 idCode, int level, u32 modulo) -{ - if(getKeyBuf() == FALSE) - return FALSE; - - keyCode[0] = idCode; - keyCode[1] = (idCode >> 1); - keyCode[2] = (idCode << 1); - - if(level >= 1) applyKeycode(modulo); - if(level >= 2) applyKeycode(modulo); - - keyCode[1] <<= 1; - keyCode[2] >>= 1; - - if(level >= 3) applyKeycode(modulo); - - return TRUE; -} +static _KEY1 enc(&MMU.ARM7_BIOS[0x0030]); u16 CFIRMWARE::getBootCodeCRC16() { @@ -164,7 +72,7 @@ u32 CFIRMWARE::decrypt(const u8 *in, u8* &out) u16 data = 0; memcpy(curBlock, in, 8); - crypt64BitDown(curBlock); + enc.decrypt(curBlock); blockSize = (curBlock[0] >> 8); if (blockSize == 0) return (0); @@ -181,7 +89,7 @@ u32 CFIRMWARE::decrypt(const u8 *in, u8* &out) if((xIn % 8) == 0) { memcpy(curBlock, in + xIn, 8); - crypt64BitDown(curBlock); + enc.decrypt(curBlock); } for(i = 0; i < 8; i++) @@ -193,14 +101,14 @@ u32 CFIRMWARE::decrypt(const u8 *in, u8* &out) if((xIn % 8) == 0) { memcpy(curBlock, in + xIn, 8); - crypt64BitDown(curBlock); + enc.decrypt(curBlock); } data |= T1ReadByte((u8*)curBlock, (xIn % 8)); xIn++; if((xIn % 8) == 0) { memcpy(curBlock, in + xIn, 8); - crypt64BitDown(curBlock); + enc.decrypt(curBlock); } len = (data >> 12) + 3; @@ -225,7 +133,7 @@ u32 CFIRMWARE::decrypt(const u8 *in, u8* &out) if((xIn % 8) == 0) { memcpy(curBlock, in + xIn, 8); - crypt64BitDown(curBlock); + enc.decrypt(curBlock); } xLen--; @@ -383,6 +291,15 @@ bool CFIRMWARE::load() return false; } +#ifdef _NEW_BOOT + if (CommonSettings.BootFromFirmware) + { + memcpy(MMU.fw.data, data, size); + MMU.fw.size = size; + return true; + } +#endif + shift1 = ((header.shift_amounts >> 0) & 0x07); shift2 = ((header.shift_amounts >> 3) & 0x07); shift3 = ((header.shift_amounts >> 6) & 0x07); @@ -400,15 +317,10 @@ bool CFIRMWARE::load() ARM9bootAddr = part1ram; ARM7bootAddr = part2ram; - if(initKeycode(header.fw_identifier, 1, 0xC) == FALSE) - { - delete [] data; - fclose(fp); - return false; - } + enc.init(header.fw_identifier, 1, 0xC); #if 0 - crypt64BitDown((u32*)&data[0x18]); + enc.applyKeycode((u32*)&data[0x18]); #else // fix touch coords data[0x18] = 0x00; @@ -422,12 +334,7 @@ bool CFIRMWARE::load() data[0x1F] = 0x00; #endif - if(initKeycode(header.fw_identifier, 2, 0xC) == FALSE) - { - delete [] data; - fclose(fp); - return false; - } + enc.init(header.fw_identifier, 2, 0xC); size9 = decrypt(data + part1addr, tmp_data9); if (!tmp_data9) diff --git a/desmume/src/firmware.h b/desmume/src/firmware.h index 784dc129a..e45c059e5 100644 --- a/desmume/src/firmware.h +++ b/desmume/src/firmware.h @@ -21,7 +21,6 @@ // the count of bytes copied from the firmware into memory #define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70 - #define FW_CONFIG_FILE_EXT "dfc" class CFIRMWARE @@ -31,14 +30,6 @@ private: u8 *tmp_data7; u32 size9, size7; - u32 keyBuf[0x412]; - u32 keyCode[3]; - - bool getKeyBuf(); - void crypt64BitUp(u32 *ptr); - void crypt64BitDown(u32 *ptr); - void applyKeycode(u32 modulo); - bool initKeycode(u32 idCode, int level, u32 modulo); u16 getBootCodeCRC16(); u32 decrypt(const u8 *in, u8* &out); u32 decompress(const u8 *in, u8* &out); diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index 24f3d3408..a1fc3c642 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -2608,6 +2608,14 @@ RelativePath="..\emufile.h" > + + + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index 6bdb79581..332182aee 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -730,6 +730,14 @@ RelativePath="..\emufile.h" > + + + + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj b/desmume/src/windows/DeSmuME_2010.vcxproj index a811b58c9..21d7a6617 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj +++ b/desmume/src/windows/DeSmuME_2010.vcxproj @@ -394,6 +394,7 @@ + @@ -660,6 +661,7 @@ + diff --git a/desmume/src/windows/DeSmuME_2010.vcxproj.filters b/desmume/src/windows/DeSmuME_2010.vcxproj.filters index 98f79a928..e6c5d60c2 100644 --- a/desmume/src/windows/DeSmuME_2010.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2010.vcxproj.filters @@ -780,6 +780,9 @@ Windows + + Core + @@ -1506,6 +1509,9 @@ Windows + + Core + diff --git a/desmume/src/windows/DeSmuME_2012.vcxproj b/desmume/src/windows/DeSmuME_2012.vcxproj index a67a3da1f..4cf3be60b 100644 --- a/desmume/src/windows/DeSmuME_2012.vcxproj +++ b/desmume/src/windows/DeSmuME_2012.vcxproj @@ -405,6 +405,7 @@ + @@ -671,6 +672,7 @@ + diff --git a/desmume/src/windows/DeSmuME_2012.vcxproj.filters b/desmume/src/windows/DeSmuME_2012.vcxproj.filters index 46b7ee184..939f7e469 100644 --- a/desmume/src/windows/DeSmuME_2012.vcxproj.filters +++ b/desmume/src/windows/DeSmuME_2012.vcxproj.filters @@ -768,6 +768,13 @@ Windows + + + + + + Core + @@ -1295,6 +1302,78 @@ Windows + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Core + @@ -1306,27 +1385,18 @@ Core\filter - - - - Core\utils\AsmJit - - - - - Windows\resources - - - Windows\resources - - - - - - - - - + + + + + + + + + + + + @@ -1340,9 +1410,6 @@ Windows\libs - - Windows\libs - Windows\libs