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