Merge branch 'master' into developer

Conflicts:
	source/config.c
	source/fs.h
	source/patches.c
This commit is contained in:
TuxSH 2016-08-15 16:29:48 +02:00
commit 24ddf5ca3d
11 changed files with 74 additions and 122 deletions

View File

@ -29,7 +29,8 @@
void configureCFW(const char *configPath) void configureCFW(const char *configPath)
{ {
clearScreens(); initScreens();
drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE); drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE);
drawString("Press A to select, START to save", 10, 30, COLOR_WHITE); drawString("Press A to select, START to save", 10, 30, COLOR_WHITE);
@ -204,4 +205,6 @@ void configureCFW(const char *configPath)
//Wait for the pressed buttons to change //Wait for the pressed buttons to change
while(HID_PAD == BUTTON_START); while(HID_PAD == BUTTON_START);
chrono(2);
} }

View File

@ -310,12 +310,9 @@ void ctrNandInit(void)
memcpy(nandCTR, shaSum, 0x10); memcpy(nandCTR, shaSum, 0x10);
if(isN3DS) if(isN3DS)
{
if(!isDevUnit)
{ {
u8 __attribute__((aligned(4))) keyY0x5[0x10] = {0x4D, 0x80, 0x4F, 0x4E, 0x99, 0x90, 0x19, 0x46, 0x13, 0xA2, 0x04, 0xAC, 0x58, 0x44, 0x60, 0xBE}; u8 __attribute__((aligned(4))) keyY0x5[0x10] = {0x4D, 0x80, 0x4F, 0x4E, 0x99, 0x90, 0x19, 0x46, 0x13, 0xA2, 0x04, 0xAC, 0x58, 0x44, 0x60, 0xBE};
aes_setkey(0x05, keyY0x5, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL); aes_setkey(0x05, keyY0x5, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
}
nandSlot = 0x05; nandSlot = 0x05;
fatStart = 0x5CAD7; fatStart = 0x5CAD7;
@ -364,8 +361,7 @@ void setRSAMod0DerivedKeys(void)
/* [3dbrew] The first 0x10-bytes are checked by the v6.0/v7.0 NATIVE_FIRM keyinit function, /* [3dbrew] The first 0x10-bytes are checked by the v6.0/v7.0 NATIVE_FIRM keyinit function,
when non-zero it clears this block and continues to do the key generation. when non-zero it clears this block and continues to do the key generation.
Otherwise when this block was already all-zero, it immediately returns. Otherwise when this block was already all-zero, it immediately returns. */
*/
memset32((void *)0x01FFCD00, 0, 0x10); memset32((void *)0x01FFCD00, 0, 0x10);
} }
} }
@ -453,11 +449,10 @@ void arm9Loader(u8 *arm9Section)
//Set keys 0x19..0x1F keyXs //Set keys 0x19..0x1F keyXs
aes_use_keyslot(0x11); aes_use_keyslot(0x11);
for(u8 slot = 0x19; slot < 0x20; slot++) for(u8 slot = 0x19; slot < 0x20; slot++, keyData[0xF]++)
{ {
aes(decKey, keyData, 1, NULL, AES_ECB_DECRYPT_MODE, 0); aes(decKey, keyData, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
keyData[0xF] += 1;
} }
} }
} }

View File

@ -51,6 +51,8 @@ bool loadSplash(void)
fileRead(fb->top_left, "/luma/splash.bin"); fileRead(fb->top_left, "/luma/splash.bin");
fileRead(fb->bottom, "/luma/splashbottom.bin"); fileRead(fb->bottom, "/luma/splashbottom.bin");
chrono(3);
return true; return true;
} }

View File

@ -57,8 +57,7 @@ void main(void)
isA9lh; isA9lh;
u32 newConfig, u32 newConfig,
emuHeader, emuHeader;
nbChronoStarted = 0;
FirmwareType firmType; FirmwareType firmType;
FirmwareSource nandType; FirmwareSource nandType;
@ -138,43 +137,24 @@ void main(void)
//Boot options aren't being forced //Boot options aren't being forced
if(needConfig != DONT_CONFIGURE) if(needConfig != DONT_CONFIGURE)
{ {
//If no configuration file exists or SELECT is held, load configuration menu
bool shouldLoadConfigurationMenu = needConfig == CREATE_CONFIGURATION || ((pressed & BUTTON_SELECT) && !(pressed & BUTTON_L1));
bool pinExists = CONFIG(7) && readPin(&pin); bool pinExists = CONFIG(7) && readPin(&pin);
if(pinExists || shouldLoadConfigurationMenu)
{
bool needToDeinit = initScreens();
//If we get here we should check the PIN (if it exists) in all cases //If we get here we should check the PIN (if it exists) in all cases
if(pinExists) verifyPin(&pin, true); if(pinExists) verifyPin(&pin, true);
//If no configuration file exists or SELECT is held, load configuration menu
bool shouldLoadConfigurationMenu = needConfig == CREATE_CONFIGURATION || ((pressed & BUTTON_SELECT) && !(pressed & BUTTON_L1));
if(shouldLoadConfigurationMenu) if(shouldLoadConfigurationMenu)
{ {
configureCFW(configPath); configureCFW(configPath);
if(!pinExists && CONFIG(7)) pin = newPin(); if(!pinExists && CONFIG(7)) pin = newPin();
//Zero the last booted FIRM flag
CFG_BOOTENV = 0;
nbChronoStarted = 1;
chrono(0);
chrono(2);
//Update pressed buttons //Update pressed buttons
pressed = HID_PAD; pressed = HID_PAD;
} }
if(needToDeinit)
{
//Turn off backlight
i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x16);
deinitScreens();
PDN_GPU_CNT = 1;
}
}
if(isA9lh && !CFG_BOOTENV && pressed == SAFE_MODE) if(isA9lh && !CFG_BOOTENV && pressed == SAFE_MODE)
{ {
nandType = FIRMWARE_SYSNAND; nandType = FIRMWARE_SYSNAND;
@ -182,28 +162,15 @@ void main(void)
} }
else else
{ {
if(CONFIG(6) && loadSplash()) pressed = HID_PAD;
/* If L and R/A/Select or one of the single payload buttons are pressed, /* If L and R/A/Select or one of the single payload buttons are pressed,
chainload an external payload (the PIN, if any, has been verified)*/ chainload an external payload (the PIN, if any, has been verified)*/
if(CONFIG(6) && loadSplash())
{
nbChronoStarted = 2;
chrono(0);
chrono(3);
nbChronoStarted = 0;
pressed = HID_PAD;
}
bool shouldLoadPayload = (pressed & SINGLE_PAYLOAD_BUTTONS) || ((pressed & BUTTON_L1) && (pressed & L_PAYLOAD_BUTTONS)); bool shouldLoadPayload = (pressed & SINGLE_PAYLOAD_BUTTONS) || ((pressed & BUTTON_L1) && (pressed & L_PAYLOAD_BUTTONS));
if(shouldLoadPayload) if(shouldLoadPayload) loadPayload(pressed);
loadPayload(pressed, nbChronoStarted != 2);
if(!CONFIG(6) && loadSplash()) if(!CONFIG(6)) loadSplash();
{
nbChronoStarted = 2;
chrono(0);
}
//If R is pressed, boot the non-updated NAND with the FIRM of the opposite one //If R is pressed, boot the non-updated NAND with the FIRM of the opposite one
if(pressed & BUTTON_R1) if(pressed & BUTTON_R1)
@ -270,12 +237,6 @@ void main(void)
break; break;
} }
if(nbChronoStarted)
{
if(nbChronoStarted == 2) chrono(3);
stopChrono();
}
launchFirm(firmType, isFirmlaunch); launchFirm(firmType, isFirmlaunch);
} }

View File

@ -81,7 +81,7 @@ void createDirectory(const char *path)
f_mkdir(path); f_mkdir(path);
} }
void loadPayload(u32 pressed, bool needToInitScreens) void loadPayload(u32 pressed)
{ {
const char *pattern; const char *pattern;
@ -107,7 +107,7 @@ void loadPayload(u32 pressed, bool needToInitScreens)
if(result == FR_OK && info.fname[0]) if(result == FR_OK && info.fname[0])
{ {
if(needToInitScreens) initScreens(); initScreens();
u32 *const loaderAddress = (u32 *)0x24FFFF00; u32 *const loaderAddress = (u32 *)0x24FFFF00;

View File

@ -34,5 +34,4 @@ u32 getFileSize(const char *path);
bool fileWrite(const void *buffer, const char *path, u32 size); bool fileWrite(const void *buffer, const char *path, u32 size);
void createDirectory(const char *path); void createDirectory(const char *path);
void findDumpFile(const char *path, char *fileName); void findDumpFile(const char *path, char *fileName);
void loadPayload(u32 pressed, bool needToInitScreens); void loadPayload(u32 pressed);u32 firmRead(void *dest, u32 firmType);
u32 firmRead(void *dest, u32 firmType);

View File

@ -39,8 +39,9 @@ bool readPin(PINData *out)
{ {
u8 __attribute__((aligned(4))) zeroes[16] = {0}; u8 __attribute__((aligned(4))) zeroes[16] = {0};
u8 __attribute__((aligned(4))) tmp[32] = {0}; u8 __attribute__((aligned(4))) tmp[32] = {0};
if(fileRead(out, "/luma/pin.bin") != sizeof(PINData)) return false; if(fileRead(out, "/luma/pin.bin") != sizeof(PINData)) return false;
else if(memcmp(out->magic, "PINF", 4) != 0) return false; if(memcmp(out->magic, "PINF", 4) != 0) return false;
computePINHash(tmp, zeroes, 1); computePINHash(tmp, zeroes, 1);
return memcmp(out->testHash, tmp, 32) == 0; //test vector verification (SD card has (or hasn't) been used on another console) return memcmp(out->testHash, tmp, 32) == 0; //test vector verification (SD card has (or hasn't) been used on another console)
@ -62,16 +63,15 @@ PINData newPin(void)
drawString("Enter your NEW PIN: ", 10, 10, COLOR_WHITE); drawString("Enter your NEW PIN: ", 10, 10, COLOR_WHITE);
u32 pressed = 0;
// Set the default value as 0x00 so we can check if there are any unentered characters. // Set the default value as 0x00 so we can check if there are any unentered characters.
u8 __attribute__((aligned(4))) enteredPassword[16 * ((PIN_LENGTH + 15) / 16)] = {0}; // pad to AES block length u8 __attribute__((aligned(4))) enteredPassword[16 * ((PIN_LENGTH + 15) / 16)] = {0}; // pad to AES block length
u32 cnt = 0;
int charDrawPos = 20 * SPACING_X; int charDrawPos = 20 * SPACING_X;
int cnt = 0;
while(true) while(true)
{ {
u32 pressed;
do do
{ {
pressed = waitInput(); pressed = waitInput();
@ -91,7 +91,6 @@ PINData newPin(void)
// we leave the rest of the array zeroed out. // we leave the rest of the array zeroed out.
if(cnt >= PIN_LENGTH) if(cnt >= PIN_LENGTH)
{ {
PINData pin = {0}; PINData pin = {0};
u8 __attribute__((aligned(4))) tmp[32] = {0}; u8 __attribute__((aligned(4))) tmp[32] = {0};
u8 __attribute__((aligned(4))) zeroes[16] = {0}; u8 __attribute__((aligned(4))) zeroes[16] = {0};
@ -114,21 +113,21 @@ PINData newPin(void)
void verifyPin(PINData *in, bool allowQuit) void verifyPin(PINData *in, bool allowQuit)
{ {
clearScreens(); initScreens();
drawString("Press START to shutdown or enter pin to proceed.", 10, 10, COLOR_WHITE); drawString("Press START to shutdown or enter pin to proceed.", 10, 10, COLOR_WHITE);
drawString("Pin: ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE); drawString("Pin: ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
u32 pressed = 0;
// Set the default characters as 0x00 so we can check if there are any unentered characters. // Set the default characters as 0x00 so we can check if there are any unentered characters.
u8 __attribute__((aligned(4))) enteredPassword[16 * ((PIN_LENGTH + 15) / 16)] = {0}; u8 __attribute__((aligned(4))) enteredPassword[16 * ((PIN_LENGTH + 15) / 16)] = {0};
u32 cnt = 0;
bool unlock; bool unlock;
int charDrawPos = 5 * SPACING_X, cnt = 0; int charDrawPos = 5 * SPACING_X;
while(true) while(true)
{ {
u32 pressed;
do do
{ {
pressed = waitInput(); pressed = waitInput();
@ -139,11 +138,7 @@ void verifyPin(PINData *in, bool allowQuit)
if(!allowQuit) pressed &= ~BUTTON_START; if(!allowQuit) pressed &= ~BUTTON_START;
if(!pressed) continue; if(!pressed) continue;
if(pressed & BUTTON_START) if(pressed & BUTTON_START) mcuPowerOff();
{
clearScreens();
mcuPowerOff();
}
char key = PINKeyToLetter(pressed); char key = PINKeyToLetter(pressed);
enteredPassword[cnt++] = (u8)key; // add character to password. enteredPassword[cnt++] = (u8)key; // add character to password.
@ -161,10 +156,6 @@ void verifyPin(PINData *in, bool allowQuit)
if(!unlock) if(!unlock)
{ {
// re zero out all 16 just in case.
memset32(enteredPassword, 0, 16);
pressed = 0;
charDrawPos = 5 * SPACING_X; charDrawPos = 5 * SPACING_X;
cnt = 0; cnt = 0;
@ -174,7 +165,7 @@ void verifyPin(PINData *in, bool allowQuit)
drawString("Pin: ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE); drawString("Pin: ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
drawString("Wrong pin! Try again!", 10, 10 + 3 * SPACING_Y, COLOR_RED); drawString("Wrong pin! Try again!", 10, 10 + 3 * SPACING_Y, COLOR_RED);
} }
else return; else break;
} }
} }
} }

View File

@ -140,10 +140,8 @@ void clearScreens(void)
invokeArm11Function(ARM11); invokeArm11Function(ARM11);
} }
bool initScreens(void) void initScreens(void)
{ {
bool needToInit = PDN_GPU_CNT == 1;
void __attribute__((naked)) ARM11(void) void __attribute__((naked)) ARM11(void)
{ {
//Disable interrupts //Disable interrupts
@ -242,18 +240,20 @@ bool initScreens(void)
WAIT_FOR_ARM9(); WAIT_FOR_ARM9();
} }
if(needToInit) if(PDN_GPU_CNT == 1)
{ {
flushDCacheRange(&config, 4); flushDCacheRange(&config, 4);
flushDCacheRange((void *)fb, sizeof(struct fb)); flushDCacheRange((void *)fb, sizeof(struct fb));
invokeArm11Function(ARM11); invokeArm11Function(ARM11);
clearScreens();
//Turn on backlight //Turn on backlight
i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A);
} }
else updateBrightness(MULTICONFIG(0)); else
{
clearScreens(); clearScreens();
updateBrightness(MULTICONFIG(0));
return needToInit; }
} }

View File

@ -42,4 +42,4 @@ static volatile struct fb {
void deinitScreens(void); void deinitScreens(void);
void updateBrightness(u32 brightnessIndex); void updateBrightness(u32 brightnessIndex);
void clearScreens(void); void clearScreens(void);
bool initScreens(void); void initScreens(void);

View File

@ -56,6 +56,8 @@ u32 waitInput(void)
void mcuReboot(void) void mcuReboot(void)
{ {
if(PDN_GPU_CNT != 1) clearScreens();
flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2);
@ -64,6 +66,8 @@ void mcuReboot(void)
void mcuPowerOff(void) void mcuPowerOff(void)
{ {
if(PDN_GPU_CNT != 1) clearScreens();
flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0); i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0);
@ -84,14 +88,19 @@ static inline void startChrono(u64 initialTicks)
for(u32 i = 1; i < 4; i++) REG_TIMER_CNT(i) = 0x84; //Count-up; enabled for(u32 i = 1; i < 4; i++) REG_TIMER_CNT(i) = 0x84; //Count-up; enabled
} }
static inline void stopChrono(void)
{
for(u32 i = 0; i < 4; i++) REG_TIMER_CNT(i) &= ~0x80;
}
void chrono(u32 seconds) void chrono(u32 seconds)
{ {
static u64 startingTicks = 0; startChrono(0);
if(!startingTicks) startChrono(0); u64 startingTicks = 0;
for(u32 i = 0; i < 4; i++) startingTicks |= REG_TIMER_VAL(i) << (16 * i);
u64 res; u64 res;
do do
{ {
res = 0; res = 0;
@ -99,18 +108,12 @@ void chrono(u32 seconds)
} }
while(res - startingTicks < seconds * TICKS_PER_SEC); while(res - startingTicks < seconds * TICKS_PER_SEC);
if(!seconds) startingTicks = res; stopChrono();
}
void stopChrono(void)
{
for(u32 i = 0; i < 4; i++) REG_TIMER_CNT(i) &= ~0x80;
} }
void error(const char *message) void error(const char *message)
{ {
initScreens(); initScreens();
clearScreens();
drawString("An error has occurred:", 10, 10, COLOR_RED); drawString("An error has occurred:", 10, 10, COLOR_RED);
int posY = drawString(message, 10, 30, COLOR_WHITE); int posY = drawString(message, 10, 30, COLOR_WHITE);

View File

@ -31,7 +31,5 @@
u32 waitInput(void); u32 waitInput(void);
void mcuReboot(void); void mcuReboot(void);
void mcuPowerOff(void); void mcuPowerOff(void);
void chrono(u32 seconds); void chrono(u32 seconds);
void stopChrono(void);
void error(const char *message); void error(const char *message);