From 70791cd9b5458492b93069c16709d01c1f736de6 Mon Sep 17 00:00:00 2001 From: d0k3 Date: Thu, 18 May 2017 12:41:34 +0200 Subject: [PATCH] Improved unit type detection code --- source/common/unittype.h | 7 +++++++ source/installer.c | 12 ++++++------ source/nand/nand.c | 20 ++++++++++---------- source/nand/nand.h | 1 - 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/source/common/unittype.h b/source/common/unittype.h index 98dfa7f..cff5f7e 100644 --- a/source/common/unittype.h +++ b/source/common/unittype.h @@ -11,3 +11,10 @@ // see: https://3dbrew.org/wiki/CONFIG11_Registers #define IS_A9LH ((*(vu32*) 0x101401C0) == 0) + +// https://www.3dbrew.org/wiki/CONFIG9_Registers +// (actually checks for an unlocked OTP) +#define IS_UNLOCKED (!((*(vu8*)0x10000000) & 0x2)) + +// A9LH + unlocked = SigHax +#define IS_SIGHAX (IS_A9LH && IS_UNLOCKED) diff --git a/source/installer.c b/source/installer.c index cbbf36f..ba88689 100644 --- a/source/installer.c +++ b/source/installer.c @@ -81,7 +81,7 @@ u32 SafeSigHaxInstaller(void) { // step #0 - a9lh check InitNandCrypto(); // for sector0x96 crypto and NAND drives - snprintf(msgA9lh, 64, CheckA9lh() ? "installed" : "not installed"); + snprintf(msgA9lh, 64, (IS_A9LH && !IS_SIGHAX) ? "installed" : "not installed"); statusA9lh = STATUS_GREEN; ShowInstallerStatus(); @@ -140,7 +140,7 @@ u32 SafeSigHaxInstaller(void) { // step #3 - check secret_sector.bin file u8 secret_sector[0x200]; - if (CheckA9lh()) { + if ((IS_A9LH && !IS_SIGHAX)) { snprintf(msgSector, 64, "checking..."); statusSector = STATUS_YELLOW; ShowInstallerStatus(); @@ -170,7 +170,7 @@ u32 SafeSigHaxInstaller(void) { statusCrypto = STATUS_RED; return 1; } - if (CheckA9lh() && !CheckSector0x96Crypto()) { + if ((IS_A9LH && !IS_SIGHAX) && !CheckSector0x96Crypto()) { snprintf(msgCrypto, 64, "OTP crypto fail"); statusCrypto = STATUS_RED; return 1; @@ -218,7 +218,7 @@ u32 SafeSigHaxInstaller(void) { statusBackup = STATUS_RED; return 1; } - if (CheckA9lh()) { + if ((IS_A9LH && !IS_SIGHAX)) { snprintf(msgBackup, 64, "0x96 backup..."); ShowInstallerStatus(); u8 sector_backup0[0x200]; @@ -255,7 +255,7 @@ u32 SafeSigHaxInstaller(void) { ShowProgress(1, 2, "FIRM install (2/2)"); snprintf(msgInstall, 64, "FIRM install (2/2)"); ShowInstallerStatus(); - if (CheckA9lh()) { + if ((IS_A9LH && !IS_SIGHAX)) { snprintf(msgInstall, 64, "0x96 revert..."); ShowInstallerStatus(); ret = SafeWriteNand(secret_sector, 0x96 * 0x200, 0x200, 0x11); @@ -269,7 +269,7 @@ u32 SafeSigHaxInstaller(void) { } else { snprintf(msgInstall, 64, "install failed"); statusInstall = STATUS_RED; - if (CheckA9lh()) { + if ((IS_A9LH && !IS_SIGHAX)) { snprintf(msgA9lh, 64, "fucked up"); statusA9lh = STATUS_RED; } diff --git a/source/nand/nand.c b/source/nand/nand.c index 761e982..632f9c2 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -14,6 +14,11 @@ static const u8 slot0x11Key95_sha256[0x20] = { // slot0x11Key95 hash (first 16 b 0xBA, 0xC1, 0x40, 0x9C, 0x6E, 0xE4, 0x1F, 0x04, 0xAA, 0xC4, 0xE2, 0x09, 0x5C, 0xE9, 0x4F, 0x78, 0x6C, 0x78, 0x5F, 0xAC, 0xEC, 0x7E, 0xC0, 0x11, 0x26, 0x9D, 0x4E, 0x47, 0xB3, 0x64, 0xC4, 0xA5 }; + +static const u8 slot0x11Key95dev_sha256[0x20] = { // slot0x11Key95 hash (first 16 byte of sector0x96) + 0x97, 0x0E, 0x52, 0x29, 0x63, 0x19, 0x47, 0x51, 0x15, 0xD8, 0x02, 0x7A, 0x22, 0x0F, 0x58, 0x15, + 0xD7, 0x6C, 0xE9, 0xAD, 0xE7, 0xFE, 0x9A, 0x25, 0x4E, 0x4A, 0x0C, 0x82, 0x67, 0xB5, 0x4A, 0x7B +}; static const u8 nand_magic_n3ds[0x60] = { // NCSD NAND header N3DS magic 0x4E, 0x43, 0x53, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -55,7 +60,7 @@ u32 LoadKeyYFromP9(u8* key, const u8* keyhash, u32 offset, u32 keyslot) u8 header[0x200]; // check arm9loaderhax - if (!CheckA9lh() || (offset < (offsetA9l + 0x0800))) return 1; + if (!IS_A9LH || (offset < (offsetA9l + 0x0800))) return 1; // section 2 (arm9loader) header of FIRM // this is @0x066A00 in FIRM90 & FIRM81 @@ -86,7 +91,7 @@ bool InitNandCrypto(void) { // part #0: KeyX / KeyY for secret sector 0x96 // on a9lh this MUST be run before accessing the SHA register in any other way - if (CheckA9lh()) { // for a9lh + if (IS_A9LH) { // for a9lh // store the current SHA256 from register memcpy(OtpSha256, (void*) REG_SHAHASH, 32); } @@ -105,7 +110,7 @@ bool InitNandCrypto(void) // part #2: TWL KEY // see: https://www.3dbrew.org/wiki/Memory_layout#ARM9_ITCM - if (CheckA9lh()) { // only for a9lh + if (IS_A9LH) { // only for a9lh u32* TwlCustId = (u32*) (0x01FFB808); u8 TwlKeyX[16] __attribute__((aligned(32))); u8 TwlKeyY[16] __attribute__((aligned(32))); @@ -132,7 +137,7 @@ bool InitNandCrypto(void) // part #3: CTRNAND N3DS KEY // thanks AuroraWright and Gelex for advice on this // see: https://github.com/AuroraWright/Luma3DS/blob/master/source/crypto.c#L347 - if (CheckA9lh()) { // only for a9lh + if (IS_A9LH) { // only for a9lh // keyY 0x05 is encrypted @0x0EB014 in the FIRM90 // keyY 0x05 is encrypted @0x0EB24C in the FIRM81 if ((LoadKeyYFromP9(slot0x05KeyY, slot0x05KeyY_sha256, 0x0EB014, 0x05) != 0) && @@ -166,7 +171,7 @@ bool CheckSector0x96Crypto(void) { u8 buffer[0x200]; ReadNandSectors(buffer, 0x96, 1, 0x11); - return (sha_cmp(slot0x11Key95_sha256, buffer, 16, SHA256_MODE) == 0); + return (sha_cmp((IS_DEVKIT) ? slot0x11Key95dev_sha256 : slot0x11Key95_sha256, buffer, 16, SHA256_MODE) == 0); } bool CheckFirmCrypto(void) @@ -184,11 +189,6 @@ bool CheckFirmCrypto(void) return true; } -bool CheckA9lh(void) -{ - return ((*(vu32*) 0x101401C0) == 0); -} - void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot) { u32 mode = (sector >= SECTOR_TWL + SIZE_TWL) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE; diff --git a/source/nand/nand.h b/source/nand/nand.h index cc34423..0dab597 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -39,7 +39,6 @@ bool InitNandCrypto(void); bool CheckSlot0x05Crypto(void); bool CheckSector0x96Crypto(void); bool CheckFirmCrypto(void); -bool CheckA9lh(void); void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot); void CryptSector0x96(void* buffer, bool encrypt);