Minor stuff

This commit is contained in:
Aurora 2016-09-19 14:57:36 +02:00
parent 420ccdcb82
commit b7b3400296
7 changed files with 130 additions and 123 deletions

View File

@ -64,7 +64,7 @@ void writeConfig(ConfigurationStatus needConfig, u32 configTemp)
}
}
void configMenu(bool oldPinStatus)
void configMenu(bool oldPinStatus, u32 oldPinMode)
{
const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )",
"Screen brightness: 4( ) 3( ) 2( ) 1( )",
@ -327,8 +327,6 @@ void configMenu(bool oldPinStatus)
}
}
u32 oldPinLength = MULTICONFIG(PIN);
//Preserve the last-used boot options (first 9 bits)
configData.config &= 0x1FF;
@ -338,7 +336,9 @@ void configMenu(bool oldPinStatus)
for(u32 i = 0; i < singleOptionsAmount; i++)
configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 21);
if(MULTICONFIG(PIN) != 0) newPin(oldPinStatus && MULTICONFIG(PIN) == oldPinLength);
u32 newPinMode = MULTICONFIG(PIN);
if(newPinMode != 0) newPin(oldPinStatus && newPinMode == oldPinMode, newPinMode);
else if(oldPinStatus) fileDelete(PIN_PATH);
//Wait for the pressed buttons to change

View File

@ -79,4 +79,4 @@ extern bool isN3DS;
bool readConfig(void);
void writeConfig(ConfigurationStatus needConfig, u32 configTemp);
void configMenu(bool oldPinStatus);
void configMenu(bool oldPinStatus, u32 oldPinMode);

View File

@ -294,22 +294,22 @@ static void sha(void *res, const void *src, u32 size, u32 mode)
/*****************************************************************/
static u8 __attribute__((aligned(4))) nandCTR[0x10];
static u8 __attribute__((aligned(4))) nandCtr[AES_BLOCK_SIZE];
static u8 nandSlot;
static u32 fatStart;
void ctrNandInit(void)
{
u8 __attribute__((aligned(4))) cid[0x10];
u8 __attribute__((aligned(4))) shaSum[0x20];
u8 __attribute__((aligned(4))) cid[AES_BLOCK_SIZE];
u8 __attribute__((aligned(4))) shaSum[SHA_256_HASH_SIZE];
sdmmc_get_cid(1, (u32 *)cid);
sha(shaSum, cid, 0x10, SHA_256_MODE);
memcpy(nandCTR, shaSum, 0x10);
sha(shaSum, cid, sizeof(cid), SHA_256_MODE);
memcpy(nandCtr, shaSum, sizeof(nandCtr));
if(isN3DS)
{
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[AES_BLOCK_SIZE] = {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);
nandSlot = 0x05;
@ -324,9 +324,9 @@ void ctrNandInit(void)
u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
{
u8 __attribute__((aligned(4))) tmpCTR[0x10];
memcpy(tmpCTR, nandCTR, 0x10);
aes_advctr(tmpCTR, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)];
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
//Read
u32 result;
@ -340,7 +340,7 @@ u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
//Decrypt
aes_use_keyslot(nandSlot);
aes(outbuf, outbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
aes(outbuf, outbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
return result;
}
@ -349,8 +349,8 @@ void set6x7xKeys(void)
{
if(!isDevUnit)
{
const u8 __attribute__((aligned(4))) keyX0x25[0x10] = {0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3};
const u8 __attribute__((aligned(4))) keyY0x2F[0x10] = {0xC3, 0x69, 0xBA, 0xA2, 0x1E, 0x18, 0x8A, 0x88, 0xA9, 0xAA, 0x94, 0xE5, 0x50, 0x6A, 0x9F, 0x16};
const u8 __attribute__((aligned(4))) keyX0x25[AES_BLOCK_SIZE] = {0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3};
const u8 __attribute__((aligned(4))) keyY0x2F[AES_BLOCK_SIZE] = {0xC3, 0x69, 0xBA, 0xA2, 0x1E, 0x18, 0x8A, 0x88, 0xA9, 0xAA, 0x94, 0xE5, 0x50, 0x6A, 0x9F, 0x16};
aes_setkey(0x25, keyX0x25, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x2F, keyY0x2F, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
@ -366,30 +366,31 @@ void decryptExeFs(u8 *inbuf)
{
u8 *exeFsOffset = inbuf + *(u32 *)(inbuf + 0x1A0) * 0x200;
u32 exeFsSize = *(u32 *)(inbuf + 0x1A4) * 0x200;
u8 __attribute__((aligned(4))) ncchCTR[0x10] = {0};
u8 __attribute__((aligned(4))) ncchCtr[AES_BLOCK_SIZE] = {0};
for(u32 i = 0; i < 8; i++)
ncchCTR[7 - i] = *(inbuf + 0x108 + i);
ncchCTR[8] = 2;
ncchCtr[7 - i] = *(inbuf + 0x108 + i);
ncchCtr[8] = 2;
aes_setkey(0x2C, inbuf, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x2C);
aes(inbuf - 0x200, exeFsOffset, exeFsSize / AES_BLOCK_SIZE, ncchCTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
aes(inbuf - 0x200, exeFsOffset, exeFsSize / AES_BLOCK_SIZE, ncchCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
}
void decryptNusFirm(u8 *inbuf, u8 *outbuf, u32 ncchSize)
{
const u8 keyY0x3D[0x10] = {0x0C, 0x76, 0x72, 0x30, 0xF0, 0x99, 0x8F, 0x1C, 0x46, 0x82, 0x82, 0x02, 0xFA, 0xAC, 0xBE, 0x4C};
u8 __attribute__((aligned(4))) cetkIv[0x10] = {0};
u8 __attribute__((aligned(4))) titleKey[0x10];
memcpy(titleKey, inbuf + 0x1BF, 0x10);
const u8 keyY0x3D[AES_BLOCK_SIZE] = {0x0C, 0x76, 0x72, 0x30, 0xF0, 0x99, 0x8F, 0x1C, 0x46, 0x82, 0x82, 0x02, 0xFA, 0xAC, 0xBE, 0x4C};
u8 __attribute__((aligned(4))) cetkIv[AES_BLOCK_SIZE] = {0};
u8 __attribute__((aligned(4))) titleKey[AES_BLOCK_SIZE];
memcpy(titleKey, inbuf + 0x1BF, sizeof(titleKey));
memcpy(cetkIv, inbuf + 0x1DC, 8);
aes_setkey(0x3D, keyY0x3D, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x3D);
aes(titleKey, titleKey, 1, cetkIv, AES_CBC_DECRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
u8 ncchIv[0x10] = {0};
u8 ncchIv[AES_BLOCK_SIZE] = {0};
aes_setkey(0x16, titleKey, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x16);
@ -400,11 +401,9 @@ void decryptNusFirm(u8 *inbuf, u8 *outbuf, u32 ncchSize)
void arm9Loader(u8 *arm9Section)
{
#ifdef DEV
//Check if FIRM is already decrypted
if(*(u32 *)(arm9Section + 0x800) == 0x47704770) return;
#endif
if(*(u32 *)(arm9Section + 0x800) != 0x47704770)
{
//Determine the arm9loader version
u32 a9lVersion;
switch(arm9Section[0x53])
@ -421,13 +420,13 @@ void arm9Loader(u8 *arm9Section)
}
//Firm keys
u8 __attribute__((aligned(4))) keyY[0x10];
u8 __attribute__((aligned(4))) arm9BinCTR[0x10];
u8 __attribute__((aligned(4))) keyY[AES_BLOCK_SIZE];
u8 __attribute__((aligned(4))) arm9BinCTR[AES_BLOCK_SIZE];
u8 arm9BinSlot = a9lVersion > 0 ? 0x16 : 0x15;
//Setup keys needed for arm9bin decryption
memcpy(keyY, arm9Section + 0x10, 0x10);
memcpy(arm9BinCTR, arm9Section + 0x20, 0x10);
memcpy(keyY, arm9Section + 0x10, sizeof(keyY));
memcpy(arm9BinCTR, arm9Section + 0x20, sizeof(arm9BinCTR));
//Calculate the size of the ARM9 binary
u32 arm9BinSize = 0;
@ -437,12 +436,12 @@ void arm9Loader(u8 *arm9Section)
if(a9lVersion > 0)
{
u8 __attribute__((aligned(4))) keyX[0x10];
u8 __attribute__((aligned(4))) keyX[AES_BLOCK_SIZE];
if(!isDevUnit)
{
const u8 __attribute__((aligned(4))) key1[0x10] = {0x07, 0x29, 0x44, 0x38, 0xF8, 0xC9, 0x75, 0x93, 0xAA, 0x0E, 0x4A, 0xB4, 0xAE, 0x84, 0xC1, 0xD8};
const u8 __attribute__((aligned(4))) key2[0x10] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0};
const u8 __attribute__((aligned(4))) key1[AES_BLOCK_SIZE] = {0x07, 0x29, 0x44, 0x38, 0xF8, 0xC9, 0x75, 0x93, 0xAA, 0x0E, 0x4A, 0xB4, 0xAE, 0x84, 0xC1, 0xD8};
const u8 __attribute__((aligned(4))) key2[AES_BLOCK_SIZE] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0};
aes_setkey(0x11, a9lVersion == 2 ? key2 : key1, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
}
@ -461,8 +460,8 @@ void arm9Loader(u8 *arm9Section)
//Set >=9.6 KeyXs
if(a9lVersion == 2 && !isDevUnit)
{
u8 __attribute__((aligned(4))) keyData[0x10] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98};
u8 __attribute__((aligned(4))) decKey[0x10];
u8 __attribute__((aligned(4))) keyData[AES_BLOCK_SIZE] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98};
u8 __attribute__((aligned(4))) decKey[sizeof(keyData)];
//Set keys 0x19..0x1F keyXs
aes_use_keyslot(0x11);
@ -472,15 +471,16 @@ void arm9Loader(u8 *arm9Section)
aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
}
}
}
}
void computePinHash(u8 *out, u8 *in)
{
u8 __attribute__((aligned(4))) cid[0x10];
u8 __attribute__((aligned(4))) cipherText[0x10];
u8 __attribute__((aligned(4))) cid[AES_BLOCK_SIZE];
u8 __attribute__((aligned(4))) cipherText[AES_BLOCK_SIZE];
sdmmc_get_cid(1, (u32 *)cid);
aes_use_keyslot(4); //Console-unique keyslot whose keys are set by the ARM9 bootROM
aes(cipherText, in, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
sha(out, cipherText, 0x10, SHA_256_MODE);
sha(out, cipherText, sizeof(cipherText), SHA_256_MODE);
}

View File

@ -70,6 +70,8 @@ void main(void)
//Attempt to read the configuration file
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
u32 devMode = MULTICONFIG(DEVOPTIONS);
//Determine if this is a firmlaunch boot
if(launchedFirmTidLow[5] != 0)
{
@ -126,26 +128,29 @@ void main(void)
if(needConfig == DONT_CONFIGURE)
{
if(MULTICONFIG(DEVOPTIONS) != 0 && isA9lh) installArm9Handlers();
if(devMode != 0 && isA9lh) installArm9Handlers();
}
//Boot options aren't being forced
else
{
bool pinExists = MULTICONFIG(PIN) != 0 && verifyPin();
u32 pinMode = MULTICONFIG(PIN);
bool pinExists = pinMode != 0 && verifyPin(pinMode);
//If no configuration file exists or SELECT is held, load configuration menu
bool shouldLoadConfigMenu = needConfig == CREATE_CONFIGURATION || ((pressed & BUTTON_SELECT) && !(pressed & BUTTON_L1));
if(shouldLoadConfigMenu)
{
configMenu(pinExists);
configMenu(pinExists, pinMode);
//Update pressed buttons
pressed = HID_PAD;
devMode = MULTICONFIG(DEVOPTIONS);
}
if(MULTICONFIG(DEVOPTIONS) != 0 && isA9lh) installArm9Handlers();
if(devMode != 0 && isA9lh) installArm9Handlers();
if(isA9lh && !CFG_BOOTENV && pressed == SAFE_MODE)
{
@ -164,7 +169,9 @@ void main(void)
}
else
{
if(MULTICONFIG(SPLASH) == 1 && loadSplash()) pressed = HID_PAD;
u32 splashMode = MULTICONFIG(SPLASH);
if(splashMode == 1 && loadSplash()) pressed = HID_PAD;
/* If L and R/A/Select or one of the single payload buttons are pressed,
chainload an external payload */
@ -173,7 +180,7 @@ void main(void)
if(shouldLoadPayload) loadPayload(pressed);
if(MULTICONFIG(SPLASH) == 2) loadSplash();
if(splashMode == 2) loadSplash();
//Determine if the user chose to use the SysNAND FIRM as default for a R boot
bool useSysAsDefault = isA9lh ? CONFIG(USESYSFIRM) : false;
@ -246,15 +253,14 @@ void main(void)
switch(firmType)
{
case NATIVE_FIRM:
patchNativeFirm(firmVersion, nandType, emuHeader, isA9lh);
patchNativeFirm(firmVersion, nandType, emuHeader, isA9lh, devMode);
break;
case SAFE_FIRM:
case NATIVE_FIRM1X2X:
if(isA9lh) patch1x2xNativeAndSafeFirm();
if(isA9lh) patch1x2xNativeAndSafeFirm(devMode);
break;
default:
//Skip patching on unsupported O3DS AGB/TWL FIRMs
if(isN3DS || firmVersion >= (firmType == TWL_FIRM ? 0x16 : 0xB)) patchLegacyFirm(firmType);
patchLegacyFirm(firmType, firmVersion, devMode);
break;
}
@ -331,7 +337,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
return firmVersion;
}
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh)
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh, u32 devMode)
{
u8 *arm9Section = (u8 *)firm + section[2].offset,
*arm11Section1 = (u8 *)firm + section[1].offset;
@ -387,9 +393,9 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
//Apply UNITINFO patch
if(MULTICONFIG(DEVOPTIONS) == 2) patchUnitInfoValueSet(arm9Section, section[2].size);
if(devMode == 2) patchUnitInfoValueSet(arm9Section, section[2].size);
if(isA9lh && MULTICONFIG(DEVOPTIONS) != 0)
if(devMode != 0 && isA9lh)
{
//ARM11 exception handlers
u32 codeSetOffset,
@ -412,7 +418,7 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
}
}
static inline void patchLegacyFirm(FirmwareType firmType)
static inline void patchLegacyFirm(FirmwareType firmType, u32 firmVersion, u32 devMode)
{
u8 *arm9Section = (u8 *)firm + section[3].offset;
@ -423,13 +429,14 @@ static inline void patchLegacyFirm(FirmwareType firmType)
firm->arm9Entry = (u8 *)0x801301C;
}
if(isN3DS || firmVersion >= (firmType == TWL_FIRM ? 0x16 : 0xB))
applyLegacyFirmPatches((u8 *)firm, firmType);
//Apply UNITINFO patch
if(MULTICONFIG(DEVOPTIONS) == 2) patchUnitInfoValueSet(arm9Section, section[3].size);
if(devMode == 2) patchUnitInfoValueSet(arm9Section, section[3].size);
}
static inline void patch1x2xNativeAndSafeFirm(void)
static inline void patch1x2xNativeAndSafeFirm(u32 devMode)
{
u8 *arm9Section = (u8 *)firm + section[2].offset;
@ -443,7 +450,7 @@ static inline void patch1x2xNativeAndSafeFirm(void)
}
else patchOldFirmWrites(arm9Section, section[2].size);
if(MULTICONFIG(DEVOPTIONS) != 0)
if(devMode != 0)
{
//ARM9 exception handlers
patchArm9ExceptionHandlersInstall(arm9Section, section[2].size);

View File

@ -48,8 +48,8 @@ typedef struct firmHeader {
} firmHeader;
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd);
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh);
static inline void patchLegacyFirm(FirmwareType firmType);
static inline void patch1x2xNativeAndSafeFirm(void);
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh, u32 devMode);
static inline void patchLegacyFirm(FirmwareType firmType, u32 firmVersion, u32 devMode);
static inline void patch1x2xNativeAndSafeFirm(u32 devMode);
static inline void copySection0AndInjectSystemModules(FirmwareType firmType, bool loadFromSd);
static inline void launchFirm(FirmwareType firmType, bool loadFromSd);

View File

@ -44,11 +44,11 @@ static char pinKeyToLetter(u32 pressed)
return keys[31 - i];
}
void newPin(bool allowSkipping)
void newPin(bool allowSkipping, u32 pinMode)
{
clearScreens(true, true);
u8 length = 4 + 2 * (MULTICONFIG(PIN) - 1);
u8 length = 4 + 2 * (pinMode - 1);
char *title = allowSkipping ? "Press START to skip or enter a new PIN" : "Enter a new PIN to proceed";
drawString(title, true, 10, 10, COLOR_TITLE);
@ -56,7 +56,7 @@ void newPin(bool allowSkipping)
drawCharacter('0' + length, true, 10 + 5 * SPACING_X, 10 + 2 * SPACING_Y, COLOR_WHITE);
//Pad to AES block length with zeroes
u8 __attribute__((aligned(4))) enteredPassword[0x10] = {0};
u8 __attribute__((aligned(4))) enteredPassword[AES_BLOCK_SIZE] = {0};
u8 cnt = 0;
u32 charDrawPos = 16 * SPACING_X;
@ -91,8 +91,8 @@ void newPin(bool allowSkipping)
pin.formatVersionMinor = PIN_VERSIONMINOR;
pin.length = length;
u8 __attribute__((aligned(4))) tmp[0x20];
u8 __attribute__((aligned(4))) zeroes[0x10] = {0};
u8 __attribute__((aligned(4))) tmp[SHA_256_HASH_SIZE];
u8 __attribute__((aligned(4))) zeroes[AES_BLOCK_SIZE] = {0};
computePinHash(tmp, zeroes);
memcpy(pin.testHash, tmp, sizeof(tmp));
@ -104,7 +104,7 @@ void newPin(bool allowSkipping)
error("Error writing the PIN file");
}
bool verifyPin(void)
bool verifyPin(u32 pinMode)
{
PinData pin;
@ -112,11 +112,11 @@ bool verifyPin(void)
memcmp(pin.magic, "PINF", 4) != 0 ||
pin.formatVersionMajor != PIN_VERSIONMAJOR ||
pin.formatVersionMinor != PIN_VERSIONMINOR ||
pin.length != 4 + 2 * (MULTICONFIG(PIN) - 1))
pin.length != 4 + 2 * (pinMode - 1))
return false;
u8 __attribute__((aligned(4))) zeroes[0x10] = {0};
u8 __attribute__((aligned(4))) tmp[0x20];
u8 __attribute__((aligned(4))) zeroes[AES_BLOCK_SIZE] = {0};
u8 __attribute__((aligned(4))) tmp[SHA_256_HASH_SIZE];
computePinHash(tmp, zeroes);
@ -126,7 +126,7 @@ bool verifyPin(void)
initScreens();
//Pad to AES block length with zeroes
u8 __attribute__((aligned(4))) enteredPassword[0x10] = {0};
u8 __attribute__((aligned(4))) enteredPassword[AES_BLOCK_SIZE] = {0};
bool unlock = false;
u8 cnt = 0;

View File

@ -42,5 +42,5 @@ typedef struct __attribute__((packed))
u8 hash[32];
} PinData;
void newPin(bool allowSkipping);
bool verifyPin(void);
void newPin(bool allowSkipping, u32 pinMode);
bool verifyPin(u32 pinMode);